Creation - - 13/04/2020

This notebook aims at exploring the Cetacean occurrence dataset from the PaleoBiology DataBase (PBDB), looking for potential biases invalidating to our model assumptions and how to mitigate them. Subsampling this dataset will allow (1) to reduce the computational burden of our analysis and (2) to compensate for the biases mentioned above.

Load occurrence dataset

Load the list of occurrences with morphological information

These are the specimens that are already included in the tree thanks to their morphological characters, and must therefore be removed from the occurrence dataset.

Combine these taxa with extant taxa to get all the species included in the tree.

Idem at the generic level for the genus analysis.

Remove those occurrences from our initial dataset to avoid redundancy.

Explore the dataset

Repartition through time

Full fossil record

Each occurrence is associated with a stratigraphic age uncertainty interval (minimum and maximum ages).

First, one can use the stratigraphic age uncertainty interval midpoint as the occurrence fixed age.

\(\to\) Numerous occurrences seem to have the same stratigraphic age uncertainty so in order to avoid clusters let’s draw them uniformly in their interval rather than taking the midpoint.

\(\to\) The distribution seems much smoother now.

Uniform subsampling

These occurrences are too numerous to perform a quick preliminary analysis, so let’s randomly subsample a fraction of them.

\(\to\) The distribution looks similar, with some noise due to higher variance with smaller sample.

Repartition among accepted ranks

Occurrences are associated with an accepted rank, depending on the level of detail of their description and attribution to a given taxonomic position.

Pie chart

\(\to\) Half of the occurrences are identified at the level of the species and 1/3 at the genus or family.

Some clades are unranked:


  Chaeomysticeti          Neoceti Panphyseteroidea       Pelagiceti  Platanidelphidi       Squaloceti 
              26                2                1                1                1                1 

Time repartition by rank

\(\to\) An apparent huge cluster of occurrences appears in recent times, with very precise dating = Artifact due to the “Pull of the Recent” effect ? Bones collected by ancient hominids ?

\(\implies\) These occurrences seem to obey to a completely different process and over a very short period of time, so we decided to remove all Late Pleistocene and Holocene occurrences in order to avoid this bias.

BIAS CORRECTION N°1: Remove all Late Pleistocene and Holocene occurrences

\(\to\) The distributions are much more homogeneous after the correction. Similar trends can be observed at each rank, with peaks at ~15My and ~5My.

Redundancy of occurrences with the same accepted name

\(\to\) ~Half of species/genera/subfamilies have only one specimen by accepted name, but it could go up to ~50 within the same species and ~200 occurrences within the same suborder. In our model all species are upposed to have the same abundance (identical sampling rates among branches), so those huge differences will have to be mitigated. See later for a quantification of this discrepancy and a comparison with our model’s assumptions

\(\implies\) Our goal now will be to correct this abundance bias.

Mitigate the abundance bias

To quantify more precisely this bias, we will:

  1. Count the number of occurrences for each taxon
  2. Obtain the stratigraphic range of each taxa - ie. the time interval in which a taxon is observed - by combining the stratigraphic age uncertainties of its occurrences
  3. Compute the density of occurrences = nb of occurrences / stratigraphic range, expressed in “number of occurrences by million years”

Compute the occurrence density

Count occurrences by accepted name

Count the number of occurrences with the same accepted name and plot their distribution.

\(\to\) Some occurrences have too much age uncertainty (unrelated to taxon longevity in extreme cases like the one spanning 60My), they risk to artificially increase species duration.

BIAS CORRECTION N°2: Exclude occurrences with highly uncertain dating (> 10My)

Most of occurrences show less than 10 My age uncertainty, let’s keep only these ones.

\(\to\) The removal of highly uncertain occurrences seems to be only a little biased, even if uncertainty globally increases with age.

\(\to\) Some taxa have several occurrences with distinct age uncertainty intervals, let’s combine them into a unique stratigraphic range.

Stratigraphic ranges = unique time interval combining age uncertainties of occurrences of the same taxon (excluding the most uncertain ones)

Density distributions

Plot the density of occurrences (= number of occurrences by unit of time, in the stratigraphic interval of a taxon) for each taxonomic rank.

\(\to\) Density logically increases with taxa ranks, but the distributions for species and genera dramatically spread over two orders of magnitude.

Correlation between occurrence density and age

If we want to correct species abundance differences based on the density of occurrences in the age interval, those factors should not depend on time in order to avoid penalizing periods with higher densities.

Let’s compare the occurrence densities computed with the initial time ranges and the combined densities computed with the combined stratigraphic ranges.

\(\to\) The density based on combined ranges seems less time-dependent than the density based on initial time ranges. We will therefore use the combined density for our corrections.

BIAS CORRECTION N°3: Subsample occurrences by homogenizing the combined occurrence density

Subsampling by homogenization = reducing the discrepancy between high and low occurrence densities among taxa by subsampling preferentially the densest ones.

Compare densities by accepted name count (species only)

Let’s focus now on the occurrences accepted at the species level because they are the one for which we can correct the abundance bias by subsampling the most concentrated combined intervals.

\(\to\) Their is a huge span of densities driven by the number of occurrences for the same species that we can reduce by subsampling the most concentrated intervals.

Impact of correcting subsampling on density distributions (species only)

\(\to\) Subsampling by homogenization successfully reduces the density span from 2 to 1 order of magnitude.

Impact of subsampling on occurrences repartition (species only)

See what our distributions look like after subsampling:

\(\to\) Some highly dense cluster became much more similar to the others.

If we superpose these 2 plots:

\(\to\) We get the new species occurrence distribution after subsampling, that could be used for doing inference with the occurrence birth-death model.

Compare with a Poisson sampling process

In order to check if the data fit our assumptions of constant-fossilization-rate Poisson sampling we compare the observed occurrences distributions with the expected ones. Specifically, we will look at the number of taxa represented by 1, 2, 3, … occurrences and the one that we would expect for a given distribution of stratigraphic ranges (seen here as a proxy for species duration).

In a Poisson process with occurrence sampling rate \(\omega\) and for a given time interval of length \(t\), the probability of observing \(N_t = k\) occurrences is given by the Poisson distribution of mean of parameter \(\omega\times t\):

\[\mathbb{P}(N_t=k) = e^{-\omega t}\frac{(\omega t)^k}{k!}\]

So in order to have the absolute probability of observing \(N_0 = n\) occurrences we have to integrate over the full distribution of age uncertainties \(t\), called \(f(t)\):

\[\mathbb{P}(N_0 = n) = \int_t P(N_t = n) f(t) dt = \int_t e^{-\omega t}\frac{(\omega t)^n}{n!} f(t) dt\]

First, approximate this distribution:

Then integrate and plot the expected distribution for a given omega:

Finally, try to find an \(\omega\) value that approximately fits the first points (the least affected by oversampling biases) and check if the other points follow the expected curve:

\(\implies\) Initial observations really do not fit the expectations, species with more than 5 occurrences must remain very rare ! But our subsampling seems to correct most of this bias.

However, this method requires to make several arbitrary choices that may introduce new biases so we will instead subsample at other levels (palaeontological collection, geological formation). In each case only one occurrence will be sampled for the similarly identified, a process we will refer to as aggregating these occurrences according to the chosen factor.

BIAS CORRECTION N°3bis: Subsample occurrences by aggregating similarly identified occurrences in each collection

Subsampling by aggregation = aggregate all the occurrences of a given taxon according to a given criterion (collection, geological formation, country, geological plate).

Wrong track: Aggregate similarly identified occurrences in each collection

In order to reduce the abundance bias, we may keep only one occurrence for each collection:

\(\to\) Not enough occurrences are removed to make a sufficient difference. If we look at the collection with the highest number of occurrences:


        Aprixokogia kelloggi                      Balaena   Balaenoptera acutorostrata 
                           1                            2                            2 
             Balaenopteridae                    Balaenula      Bohaskaia monodontoides 
                           2                            2                            1 
               Cetotheriinae               Delphinapterus                  Delphinidae 
                           1                            3                            2 
                   Delphinus                 Globicephala          Gricetoides aurorae 
                           2                            2                            1 
              Herpetocetinae       Herpetocetus sendaicus Herpetocetus transatlanticus 
                           1                            1                            1 
             Kogia breviceps                     Kogiidae                     Kogiinae 
                           1                            1                            2 
         Kogiopsis floridana               Lagenorhynchus     Lagenorhynchus harmatuki 
                           1                            2                            1 
                   Megaptera      Mesoplodon longirostris                      Monodon 
                           2                            2                            1 
    Ninoziphius platyrostris                Orycterocetus       Physeter macrocephalus 
                           3                            1                            1 
                Physeteridae                 Physeterinae           Physeterula dubusi 
                           1                            2                            1 
                 Plesiocetus        Pliopontos littoralis                   Pontoporia 
                           1                            1                            1 
               Pontoporiidae                    Pseudorca                  Scaldicetus 
                           2                            2                            1 
                    Stenella                Stenella rayi                     Tursiops 
                           2                            1                            2 
         Ziphius cavirostris 
                           2 

\(\to\) There are very few redundancies among the accepted names in collections so aggregating those won’t reduce the abundance bias.

Instead, we may try to aggregate occurrences with the same accepted name at the level of the geological formation (ie subsample only one for each).

Aggregate similarly identified occurrences in each formation

\(\to\) In that case the sub-sampling is big enough to hope correcting our bias.

\(\to\) The initial bias is mostly corrected.

Removed 2 rows containing missing values (geom_bar).Removed 2 rows containing missing values (geom_bar).

\(\to\) Comparing with the initial occurrences distribution and with the distribution after our first sub-sampling it appears that both methods lead to very similar distributions. This comforts us about the robustness of those approaches.

However, we have to take into account the occurrences that do not have any indicated geological formation to subsample them separately.

Wrong track: Aggregate occurrences without formation by country + early interval

To approximate geological formation we chose to proceed to the aggregation based on the combination of the country and the early stratigraphic interval.

More occurrences remain after aggregating with this new method. Let’s compare again with the theoretical distribution:

\(\to\) The correspondence is still good, except for two taxa:


   Scaldicetus grandis Schizodelphis sulcatus 
                    14                     16 

Removed 2 rows containing missing values (geom_bar).Removed 2 rows containing missing values (geom_bar).

Saving 10 x 5 in image

\(\to\) Comparing with the initial occurrences distribution and with the distribution after our first sub-sampling it appears that both methods lead to very similar distributions. This comforts us about the robustness of those approaches.

Replacing countries by geological plates seems to make more sens from a palaeontological perspective, so let’s try it.

Aggregate occurrences without formation by geoplate + early interval

More occurrences remain after aggregating with this new method. Let’s compare again with the theoretical distribution:

\(\to\) The correspondence is still good, except for two taxa:


   Scaldicetus grandis Schizodelphis sulcatus 
                    13                     15 
Removed 2 rows containing missing values (geom_bar).Removed 2 rows containing missing values (geom_bar).

\(\to\) Delimiting by geological plates (+ age) instead of countries (+ age) leads to similar distributions, so we will keep it.

Check that the sampling methods do not introduce biases in the repartition between Odontoceti and Mysticeti

Mystecetes are usually larger than odontocetes, and size is associated with a wider geographic range so since we are subsampling occurrences according to geological formation we may be biasing our data towards more widespread species, therefore towards mystecetes.

Look at the families first:

\(\to\) The family distributions vary a bit after subsampling, but because of the limited number of species by family the fact that we corrected the oversampling of some species could have a disproportionate effect.

Let’s look rather at a higher taxonomic rank, by importing the topology of cetacean families (from Marx et al. 2016):

\(\to\) There is a smaller proportion of archeocete occurrences after either sampling, because a huge cluster is subsampled around 35 My ago, but this effect is expected. However, for the Mysticeti vs. Odotoceti there is no huge apparent bias, especially with the aggregating method.

Faster genus-level analysis

Apply the same transformations at the generic level to perform the analysis faster.

More occurrences remain after aggregating with this new method. Let’s compare again with the theoretical distribution:

\(\to\) The correspondence is much less improved than with species aggregation because some genera have a lot of occurrences due to their high number of species:


Balaenoptera   Kentriodon   Mesoplodon  Scaldicetus    Squalodon 
          53           27           30           41           40 
Removed 2 rows containing missing values (geom_bar).Removed 2 rows containing missing values (geom_bar).

\(\to\) Delimiting by geological plates (+ age) instead of countries (+ age) leads to similar distributions, with a bit more occurrences.

Conclusions

Several biases affect the cetacean fossil record:

LS0tCnRpdGxlOiAiRm9ybWF0IENldGFjZWFucyBEYXRhIgpvdXRwdXQ6CiAgcGRmX2RvY3VtZW50OiAKICAgIGZpZ19oZWlnaHQ6IDUuNQogICAgZmlnX3dpZHRoOiAxMAogICAgdG9jOiB5ZXMKICBodG1sX25vdGVib29rOgogICAgY29kZV9mb2xkaW5nOiBoaWRlCiAgaHRtbF9kb2N1bWVudDoKICAgIGZpZ193aWR0aDogMTAKICAgIHRvYzogeWVzCi0tLQoKQ3JlYXRpb24gLSBqZXJlbXkuYW5kcmVvbGV0dGlAZW5zLmZyIC0gMTMvMDQvMjAyMAoKVGhpcyBub3RlYm9vayBhaW1zIGF0IGV4cGxvcmluZyB0aGUgQ2V0YWNlYW4gb2NjdXJyZW5jZSBkYXRhc2V0IGZyb20gdGhlIFBhbGVvQmlvbG9neSBEYXRhQmFzZSAoUEJEQiksIGxvb2tpbmcgZm9yIHBvdGVudGlhbCBiaWFzZXMgaW52YWxpZGF0aW5nIHRvIG91ciBtb2RlbCBhc3N1bXB0aW9ucyBhbmQgaG93IHRvIG1pdGlnYXRlIHRoZW0uIFN1YnNhbXBsaW5nIHRoaXMgZGF0YXNldCB3aWxsIGFsbG93ICgxKSB0byByZWR1Y2UgdGhlIGNvbXB1dGF0aW9uYWwgYnVyZGVuIG9mIG91ciBhbmFseXNpcyBhbmQgKDIpIHRvIGNvbXBlbnNhdGUgZm9yIHRoZSBiaWFzZXMgbWVudGlvbmVkIGFib3ZlLgoKYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0V9CmtuaXRyOjpvcHRzX2NodW5rJHNldChlY2hvID0gRkFMU0UpCmBgYAoKYGBge3IgaW5jbHVkZT1GQUxTRX0KbGlicmFyeSgiZ2dwbG90MiIpCmxpYnJhcnkoImRwbHlyIikKbGlicmFyeSgiZ2d0cmVlIikKYGBgCgojIExvYWQgb2NjdXJyZW5jZSBkYXRhc2V0CgpgYGB7ciwgaW5jbHVkZT1GfQojIGNldGFjZWFfcGJkYiA8LSByZWFkLmNzdigiLi4vZGF0YS1jZXRhY2VhbnMvY2V0YWNlYV9wYmRiXzA1X0Fwcl8yMDE4LmNzdiIsIHNraXAgPSAxNikKY2V0YWNlYV9wYmRiIDwtIHJlYWQuY3N2MigiLi4vZGF0YS1jZXRhY2VhbnMvY2V0YWNlYV9wYmRiXzExX01heV8yMDIwLmNzdiIsIHNraXAgPSAxNykKIyBSZW1vdmUgY29sdW1ucyB3aXRoIG9ubHkgTkFzCmNldGFjZWFfcGJkYiA8LSBjZXRhY2VhX3BiZGJbLGNvbFN1bXMoaXMubmEoY2V0YWNlYV9wYmRiKSkgPCBucm93KGNldGFjZWFfcGJkYildCiMgUmVjb3JkIGNsYXNzeWluZyBudW1iZXJzIGFzIGZhY3RvcnMKY2V0YWNlYV9wYmRiWywgZ3JlcCgiX25vIiwgbmFtZXMoY2V0YWNlYV9wYmRiKSwgdmFsdWUgPSBUKV0gPC0gZGF0YS5mcmFtZShzYXBwbHkoY2V0YWNlYV9wYmRiWywgZ3JlcCgiX25vIiwgbmFtZXMoY2V0YWNlYV9wYmRiKSwgdmFsdWUgPSBUKV0sIGFzLmZhY3RvcikpCiMgUmVjb3JkIG51bWVyaWMgcXVhbnRpdGllcyBhcyBkb3VibGVzCmNldGFjZWFfcGJkYlssIGMoImxhdCIsICJsbmciLCAicGFsZW9sYXQiLCAicGFsZW9sbmciLCAibWluX21hIiwgIm1heF9tYSIpXSA8LSBzYXBwbHkoY2V0YWNlYV9wYmRiWywgYygibGF0IiwgImxuZyIsICJwYWxlb2xhdCIsICJwYWxlb2xuZyIsICJtaW5fbWEiLCAibWF4X21hIildLCBmdW5jdGlvbihjb2wpe2FzLm51bWVyaWMoYXMuY2hhcmFjdGVyKGNvbCkpfSkKIyBzdW1tYXJ5KGNldGFjZWFfcGJkYltncmVwKCJjb21tZW50IiwgbmFtZXMoY2V0YWNlYV9wYmRiKSwgdmFsdWUgPSBULCBpbnZlcnQ9VCldKQpuYW1lcyhjZXRhY2VhX3BiZGIpCmBgYAoKYGBge3IsIGluY2x1ZGU9Rn0KaGVhZChjZXRhY2VhX3BiZGIpCmBgYAoKYGBge3IsIGluY2x1ZGU9Rn0KIyBSZW9yZGVyIGFjY2VwdGVkIHJhbmtzIGFjY29yZGluZyB0byBjbGFzc2lmaWNhdGlvbiBzdGFuZGFyZC4KCmxldmVscyhjZXRhY2VhX3BiZGIkYWNjZXB0ZWRfcmFuaykKY2V0YWNlYV9wYmRiJGFjY2VwdGVkX3JhbmsgPC0gZmFjdG9yKGNldGFjZWFfcGJkYiRhY2NlcHRlZF9yYW5rLCBsZXZlbHM9Yygic3Vic3BlY2llcyIsICJzcGVjaWVzIiwgImdlbnVzIiwgInN1YmZhbWlseSIsICJmYW1pbHkiLCAic3VwZXJmYW1pbHkiLCAiaW5mcmFvcmRlciIsICJzdWJvcmRlciIsICJvcmRlciIsICJ1bnJhbmtlZCBjbGFkZSIpKQpjZXRhY2VhX3BiZGIkaWRlbnRpZmllZF9yYW5rIDwtIGZhY3RvcihjZXRhY2VhX3BiZGIkaWRlbnRpZmllZF9yYW5rLCBsZXZlbHM9Yygic3Vic3BlY2llcyIsICJzcGVjaWVzIiwgImdlbnVzIiwgInN1YmZhbWlseSIsICJmYW1pbHkiLCAic3VwZXJmYW1pbHkiLCAiaW5mcmFvcmRlciIsICJzdWJvcmRlciIsICJvcmRlciIsICJ1bnJhbmtlZCBjbGFkZSIpKQpgYGAKCiMgTG9hZCB0aGUgbGlzdCBvZiBvY2N1cnJlbmNlcyB3aXRoIG1vcnBob2xvZ2ljYWwgaW5mb3JtYXRpb24KClRoZXNlIGFyZSB0aGUgc3BlY2ltZW5zIHRoYXQgYXJlIGFscmVhZHkgaW5jbHVkZWQgaW4gdGhlIHRyZWUgdGhhbmtzIHRvIHRoZWlyIG1vcnBob2xvZ2ljYWwgY2hhcmFjdGVycywgYW5kIG11c3QgdGhlcmVmb3JlIGJlIHJlbW92ZWQgZnJvbSB0aGUgb2NjdXJyZW5jZSBkYXRhc2V0LgoKYGBge3IsIGluY2x1ZGU9Rn0Kb2NjdXJyZW5jZXNfd2l0aF9tb3JwaG9sb2d5IDwtIHJlYWQuY3N2MigiLi4vZGF0YS1jZXRhY2VhbnMvU3BlY2ltZW5zUEJEQl9uZXdOYW1lcy5jc3YiKQpzdW1tYXJ5KG9jY3VycmVuY2VzX3dpdGhfbW9ycGhvbG9neSkKYGBgCgpDb21iaW5lIHRoZXNlIHRheGEgd2l0aCBleHRhbnQgdGF4YSB0byBnZXQgYWxsIHRoZSBzcGVjaWVzIGluY2x1ZGVkIGluIHRoZSB0cmVlLgoKYGBge3IsIGluY2x1ZGU9Rn0KZXh0YW50X3RheGEgPC0gcmVhZC5jc3YyKCIuLi9kYXRhLWNldGFjZWFucy9DZXRhY2VhX2V4dGFudF90YXhhLmNzdiIpCnN1bW1hcnkoZXh0YW50X3RheGEpCmBgYAoKYGBge3IsIGluY2x1ZGU9Rn0KZXh0aW5jdF90YXhhIDwtIGNldGFjZWFfcGJkYltjZXRhY2VhX3BiZGIkb2NjdXJyZW5jZV9ubyAlaW4lIG9jY3VycmVuY2VzX3dpdGhfbW9ycGhvbG9neSRwYmRiX29jY3VyZW5jZS5udW1iZXIsIGMoImFjY2VwdGVkX25hbWUiLCAibWluX21hIiwgIm1heF9tYSIpXQpleHRpbmN0X3RheGEkYWNjZXB0ZWRfbmFtZSA8LSBhcy5mYWN0b3IoZ3N1YigiICIsICJfIiwgZXh0aW5jdF90YXhhJGFjY2VwdGVkX25hbWUpKQpuYW1lcyhleHRpbmN0X3RheGEpIDwtIG5hbWVzKGV4dGFudF90YXhhKQpzdW1tYXJ5KGV4dGluY3RfdGF4YSkKYGBgCgpgYGB7ciwgaW5jbHVkZT1GfQp0YXhhIDwtIHJiaW5kKGV4dGFudF90YXhhLCBleHRpbmN0X3RheGEpCnN1bW1hcnkodGF4YSkKd3JpdGUudGFibGUodGF4YSwgZmlsZSA9ICIuLi9kYXRhLWNldGFjZWFucy9DZXRhY2VhX3RheGEuY3N2IiwgcXVvdGUgPSBGLCBzZXA9Ilx0Iiwgcm93Lm5hbWVzID0gRikKYGBgCgpgYGB7ciwgaW5jbHVkZT1GfQojIENoZWNrIHRoYXQgdGhlIG5hbWVzIGluIHRoZSBkYXRhc2V0cyBhcmUgZXhhY3RseSB0aGUgc2FtZSBhcyBpbiB0aGUgbGlzdCBhYm92ZS4KCm1vcnBob19uYW1lcyA8LSByZWFkLnRhYmxlKCIuLi9kYXRhLWNldGFjZWFucy9tb3JwaG9fc2ltcGxpZmllZF9uZXdOYW1lc19yZW1vdmVPdXRncm91cHNVbmRlc2NyaWJlZC5uZXgiLCBza2lwPTYsIGZpbGw9VCkKbW9ycGhvX25hbWVzIDwtIGRyb3BsZXZlbHMobW9ycGhvX25hbWVzJFYxW3NhcHBseShtb3JwaG9fbmFtZXMkVjEsIGdyZXBsLCBwYXR0ZXJuPSJfIildKQoKbWl0X25hbWVzIDwtIHJlYWQudGFibGUoIi4uL2RhdGEtY2V0YWNlYW5zL000Mzc2X210X3NpbXBsaWZpZWRfbmV3TmFtZXNfcmVtb3ZlT3V0Z3JvdXBzLm5leCIsIHNraXA9NiwgZmlsbD1UKQptaXRfbmFtZXMgPC0gZHJvcGxldmVscyhtaXRfbmFtZXMkVjFbc2FwcGx5KG1pdF9uYW1lcyRWMSwgZ3JlcGwsIHBhdHRlcm49Il8iKV0pCgpudWNfbmFtZXMgPC0gcmVhZC50YWJsZSgiLi4vZGF0YS1jZXRhY2VhbnMvTTQzNThfbnVjbGVhcl9zaW1wbGlmaWVkX25ld05hbWVzX3JlbW92ZU91dGdyb3Vwcy5uZXgiLCBza2lwPTYsIGZpbGw9VCkKbnVjX25hbWVzIDwtIGRyb3BsZXZlbHMobnVjX25hbWVzJFYxW3NhcHBseShudWNfbmFtZXMkVjEsIGdyZXBsLCBwYXR0ZXJuPSJfIildKQoKIyBDaGVjayB0aGF0IGFsbCB0aGUgZGF0YXNldHMgY29udGFpbiB0aGUgc2FtZSB0YXhhIG5hbWVzCnNldGVxdWFsKHRheGEkdGF4b24sIHVuaW9uKHVuaW9uKG1vcnBob19uYW1lcywgbWl0X25hbWVzKSwgbnVjX25hbWVzKSkKYGBgCgpJZGVtIGF0IHRoZSBnZW5lcmljIGxldmVsIGZvciB0aGUgZ2VudXMgYW5hbHlzaXMuCgpgYGB7ciwgaW5jbHVkZT1GfQpvY2N1cnJlbmNlc193aXRoX21vcnBob2xvZ3lfZ2VuZXJhIDwtIG9jY3VycmVuY2VzX3dpdGhfbW9ycGhvbG9neVstd2hpY2gob2NjdXJyZW5jZXNfd2l0aF9tb3JwaG9sb2d5JFRheG9uICVpbiUgYygiQXRvY2V0dXNfbmFzYWxpcyIsICJCcmFjaHlkZWxwaGlzX2phaHVheWVuc2lzIiwgIkhhYm9yb3Bob2NvZW5hX21pbnV0dXMiLCAiTG9waG9jZXR1c19yZXBlbm5pbmdpIiwgIk9kb2Jlbm9jZXRvcHNfcGVydXZpYW51cyIsICJPdGVrYWlrZWFfaHVhdGEiLCAiUGFyYXBvbnRvcG9yaWFfd2lsc29uaSIpKSxdCmV4dGFudF9nZW5lcmEgPC0gcmVhZC5jc3YyKCIuLi9kYXRhLWNldGFjZWFucy9DZXRhY2VhX2V4dGFudF9nZW5lcmEuY3N2IikKc3VtbWFyeShleHRhbnRfZ2VuZXJhKQoKZXh0aW5jdF9nZW5lcmEgPC0gY2V0YWNlYV9wYmRiW2NldGFjZWFfcGJkYiRvY2N1cnJlbmNlX25vICVpbiUgb2NjdXJyZW5jZXNfd2l0aF9tb3JwaG9sb2d5X2dlbmVyYSRwYmRiX29jY3VyZW5jZS5udW1iZXIsIGMoImFjY2VwdGVkX25hbWUiLCAibWluX21hIiwgIm1heF9tYSIpXQpleHRpbmN0X2dlbmVyYSRhY2NlcHRlZF9uYW1lIDwtIGFzLmZhY3Rvcihnc3ViKCIgIiwgIl8iLCBleHRpbmN0X2dlbmVyYSRhY2NlcHRlZF9uYW1lKSkKbmFtZXMoZXh0aW5jdF9nZW5lcmEpIDwtIG5hbWVzKGV4dGFudF9nZW5lcmEpCnN1bW1hcnkoZXh0aW5jdF9nZW5lcmEpCgpnZW5lcmEgPC0gcmJpbmQoZXh0YW50X2dlbmVyYSwgZXh0aW5jdF9nZW5lcmEpCnN1bW1hcnkoZ2VuZXJhKQp3cml0ZS50YWJsZShnZW5lcmEsIGZpbGUgPSAiLi4vZGF0YS1jZXRhY2VhbnMvQ2V0YWNlYV9nZW5lcmEuY3N2IiwgcXVvdGUgPSBGLCBzZXA9Ilx0Iiwgcm93Lm5hbWVzID0gRikKYGBgCgpgYGB7ciwgaW5jbHVkZT1GfQojIENoZWNrIHRoYXQgdGhlIG5hbWVzIGluIHRoZSBkYXRhc2V0cyBhcmUgZXhhY3RseSB0aGUgc2FtZSBhcyBpbiB0aGUgbGlzdCBhYm92ZS4KCm1vcnBob19uYW1lc19nZW5lcmEgPC0gcmVhZC50YWJsZSgiLi4vZGF0YS1jZXRhY2VhbnMvbW9ycGhvX3NpbXBsaWZpZWRfbmV3TmFtZXNfZ2VuZXJhX3JlbW92ZU91dGdyb3Vwc1VuZGVzY3JpYmVkLm5leCIsIHNraXA9NiwgZmlsbD1UKQptb3JwaG9fbmFtZXNfZ2VuZXJhIDwtIGRyb3BsZXZlbHMobW9ycGhvX25hbWVzX2dlbmVyYSRWMVtzYXBwbHkobW9ycGhvX25hbWVzX2dlbmVyYSRWMSwgZ3JlcGwsIHBhdHRlcm49Il8iKV0pCgptaXRfbmFtZXNfZ2VuZXJhIDwtIHJlYWQudGFibGUoIi4uL2RhdGEtY2V0YWNlYW5zL000Mzc2X210X3NpbXBsaWZpZWRfbmV3TmFtZXNfZ2VuZXJhX3JlbW92ZU91dGdyb3Vwcy5uZXgiLCBza2lwPTYsIGZpbGw9VCkKbWl0X25hbWVzX2dlbmVyYSA8LSBkcm9wbGV2ZWxzKG1pdF9uYW1lc19nZW5lcmEkVjFbc2FwcGx5KG1pdF9uYW1lc19nZW5lcmEkVjEsIGdyZXBsLCBwYXR0ZXJuPSJfIildKQoKbnVjX25hbWVzX2dlbmVyYSA8LSByZWFkLnRhYmxlKCIuLi9kYXRhLWNldGFjZWFucy9NNDM1OF9udWNsZWFyX3NpbXBsaWZpZWRfbmV3TmFtZXNfZ2VuZXJhX3JlbW92ZU91dGdyb3Vwcy5uZXgiLCBza2lwPTYsIGZpbGw9VCkKbnVjX25hbWVzX2dlbmVyYSA8LSBkcm9wbGV2ZWxzKG51Y19uYW1lc19nZW5lcmEkVjFbc2FwcGx5KG51Y19uYW1lc19nZW5lcmEkVjEsIGdyZXBsLCBwYXR0ZXJuPSJfIildKQoKIyBDaGVjayB0aGF0IGFsbCB0aGUgZGF0YXNldHMgY29udGFpbiB0aGUgc2FtZSB0YXhhIG5hbWVzCnNldGVxdWFsKGdlbmVyYSR0YXhvbiwgdW5pb24odW5pb24obW9ycGhvX25hbWVzX2dlbmVyYSwgbWl0X25hbWVzX2dlbmVyYSksIG51Y19uYW1lc19nZW5lcmEpKQpgYGAKClJlbW92ZSB0aG9zZSBvY2N1cnJlbmNlcyBmcm9tIG91ciBpbml0aWFsIGRhdGFzZXQgdG8gYXZvaWQgcmVkdW5kYW5jeS4KCmBgYHtyfQpjZXRhY2VhX3BiZGIgPC0gY2V0YWNlYV9wYmRiWyEoY2V0YWNlYV9wYmRiJG9jY3VycmVuY2Vfbm8gJWluJSBvY2N1cnJlbmNlc193aXRoX21vcnBob2xvZ3kkcGJkYl9vY2N1cmVuY2UubnVtYmVyKSxdCmBgYAoKIyBFeHBsb3JlIHRoZSBkYXRhc2V0CiMjIFJlcGFydGl0aW9uIHRocm91Z2ggdGltZQojIyMgRnVsbCBmb3NzaWwgcmVjb3JkCgpFYWNoIG9jY3VycmVuY2UgaXMgYXNzb2NpYXRlZCB3aXRoIGEgKipzdHJhdGlncmFwaGljIGFnZSB1bmNlcnRhaW50eSBpbnRlcnZhbCoqIChtaW5pbXVtIGFuZCBtYXhpbXVtIGFnZXMpLgoKYGBge3IgfQojIEdldCB0aGUgc3RyYXRpZ3JhcGhpYyBhZ2UgdW5jZXJ0YWludHkgaW50ZXJ2YWwKY2V0YWNlYV9wYmRiJGFnZV91bmNlcnRhaW50eV9pbnRlcnZhbCA8LSBtYXBwbHkoZnVuY3Rpb24obWluX2FnZSwgbWF4X2FnZSl7cGFzdGUoIlsiLC1tYXhfYWdlLCIsICIsLW1pbl9hZ2UsIl0iLCBzZXAgPSAiIil9LCBjZXRhY2VhX3BiZGIkbWluX21hLCBjZXRhY2VhX3BiZGIkbWF4X21hKQoKIyBDb21wdXRlIHRoZSBtZWFuIGFnZSBpbiB0aGUgaW50ZXJ2YWwKY2V0YWNlYV9wYmRiJGFnZV9tZWFuIDwtIChjZXRhY2VhX3BiZGIkbWluX21hK2NldGFjZWFfcGJkYiRtYXhfbWEpLzIKCmdncGxvdChjZXRhY2VhX3BiZGIsIGFlcyh4PS1tYXhfbWEsIHk9YWdlX3VuY2VydGFpbnR5X2ludGVydmFsKSkgKwogIGdlb21fc2VnbWVudChhZXMoeCA9IC1tYXhfbWEsIHkgPSByZW9yZGVyKGFnZV91bmNlcnRhaW50eV9pbnRlcnZhbCwgLWFnZV9tZWFuKSwgeGVuZCA9IC1taW5fbWEsIHllbmQ9cmVvcmRlcihhZ2VfdW5jZXJ0YWludHlfaW50ZXJ2YWwsIC1hZ2VfbWVhbiksIGNvbG9yPS1hZ2VfbWVhbikpICsKICBzY2FsZV94X2NvbnRpbnVvdXMobmFtZSA9ICJUaW1lIChNeSkiKSArCiAgc2NhbGVfeV9kaXNjcmV0ZShuYW1lID0gIk9jY3VycmVuY2VzIikgKwogIGxhYnMoY29sb3VyPSJNZWFuIGFnZSIpICsKICBnZ3RpdGxlKCJEaXN0cmlidXRpb24gb2YgYWdlIGludGVydmFscyIpICsKICB0aGVtZShheGlzLnRleHQueT1lbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50aWNrcy55PWVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBwYW5lbC5ncmlkLm1ham9yLnkgPSBlbGVtZW50X2JsYW5rKCkpCmBgYAoKRmlyc3QsIG9uZSBjYW4gdXNlIHRoZSBzdHJhdGlncmFwaGljIGFnZSB1bmNlcnRhaW50eSBpbnRlcnZhbCBtaWRwb2ludCBhcyB0aGUgb2NjdXJyZW5jZSBmaXhlZCBhZ2UuCgpgYGB7ciwgZmlnLmFzcD0wLjMsIGZpZy53aWR0aD04fQpnZ3Bsb3QoY2V0YWNlYV9wYmRiLCBhZXMoeD0tYWdlX21lYW4sIHk9cm5vcm0obGVuZ3RoKGFnZV9tZWFuKSwgMSwgMC4wNSkpKSArCiAgZ2VvbV9wb2ludChjZXg9MC4xLCBhbHBoYT0wLjUpICsKICBzY2FsZV94X2NvbnRpbnVvdXMobmFtZSA9ICJUaW1lIChNeSkiKSArCiAgc2NhbGVfeV9jb250aW51b3VzKG5hbWUgPSAiT2NjdXJyZW5jZXMiLCBsaW1pdHMgPSBjKDAuNywgMS4zKSkgKwogIHNjYWxlX2ZpbGxfZGlzY3JldGUobmFtZT0iQWNjZXB0ZWQgcmFuayIpICsKICB0aGVtZShwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIGF4aXMubGluZS54ID0gZWxlbWVudF9saW5lKHNpemUgPSAwLjUsIGxpbmV0eXBlID0gInNvbGlkIiwgY29sb3VyID0gImJsYWNrIiksCiAgICAgICAgYXhpcy50ZXh0LnkgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50aWNrcy55ID0gZWxlbWVudF9ibGFuaygpKSArCiAgZ2d0aXRsZShwYXN0ZSgiUmVwYXJ0aXRpb24gb2YiLCBkaW0oY2V0YWNlYV9wYmRiKVsxXSwgInJlY29yZGVkIG9jY3VycmVuY2VzIHRocm91Z2ggdGltZSAtIE1pZHBvaW50IikpCgpnZ3Bsb3QoY2V0YWNlYV9wYmRiLCBhZXMoeD0tYWdlX21lYW4pKSArCiAgZ2VvbV9oaXN0b2dyYW0oYmlud2lkdGggPSAxKSArCiAgc2NhbGVfeF9jb250aW51b3VzKG5hbWUgPSAiVGltZSAoTXkpIikgKwogIHNjYWxlX3lfY29udGludW91cyhuYW1lID0gIk51bWJlciBvZiBvY2N1cnJlbmNlcyIpICsKICBzY2FsZV9maWxsX2Rpc2NyZXRlKG5hbWU9IkFjY2VwdGVkIHJhbmsiKSArCiAgdGhlbWUocGFuZWwuZ3JpZC5tYWpvci55ID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIGxlZ2VuZC5wb3NpdGlvbj0iYm90dG9tIikgKwogIGdndGl0bGUocGFzdGUoIkV2b2x1dGlvbiBvZiB0aGUgbnVtYmVyIG9jY3VycmVuY2VzIHRocm91Z2ggdGltZSAoIHRvdGFsIG9mIiwgZGltKGNldGFjZWFfcGJkYilbMV0sICIpIC0gTWlkcG9pbnQiKSkKYGBgCgokXHRvJCBOdW1lcm91cyBvY2N1cnJlbmNlcyBzZWVtIHRvIGhhdmUgdGhlIHNhbWUgc3RyYXRpZ3JhcGhpYyBhZ2UgdW5jZXJ0YWludHkgc28gaW4gb3JkZXIgdG8gYXZvaWQgY2x1c3RlcnMgbGV0J3MgZHJhdyB0aGVtIHVuaWZvcm1seSBpbiB0aGVpciBpbnRlcnZhbCByYXRoZXIgdGhhbiB0YWtpbmcgdGhlIG1pZHBvaW50LgoKYGBge3IsIGZpZy5hc3A9MC4zLCBmaWcud2lkdGg9OH0KIyBEcmF3IG9jY3VycmVuY2UgYWdlIHVuaWZvcm1hbGx5IGluIHRoZSB1bmNlcnRhaW50eSBpbnRlcnZhbApjZXRhY2VhX3BiZGIkYWdlX3J1bmlmIDwtIG1hcHBseShmdW5jdGlvbihtLCBNKXtydW5pZihuPTEsIG1pbj1tLCBtYXg9TSl9LCBjZXRhY2VhX3BiZGIkbWluX21hLCBjZXRhY2VhX3BiZGIkbWF4X21hKQoKZ2dwbG90KGNldGFjZWFfcGJkYiwgYWVzKHg9LWFnZV9ydW5pZiwgeT1ybm9ybShsZW5ndGgoYWdlX3J1bmlmKSwgMSwgMC4wNSkpKSArCiAgZ2VvbV9wb2ludChjZXg9MC4xLCBhbHBoYT0wLjUpICsKICBzY2FsZV94X2NvbnRpbnVvdXMobmFtZSA9ICJUaW1lIChNeSkiKSArCiAgc2NhbGVfeV9jb250aW51b3VzKG5hbWUgPSAiT2NjdXJyZW5jZXMiLCBsaW1pdHMgPSBjKDAuNywgMS4zKSkgKwogIHNjYWxlX2ZpbGxfZGlzY3JldGUobmFtZT0iQWNjZXB0ZWQgcmFuayIpICsKICB0aGVtZShwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIGF4aXMubGluZS54ID0gZWxlbWVudF9saW5lKHNpemUgPSAwLjUsIGxpbmV0eXBlID0gInNvbGlkIiwgY29sb3VyID0gImJsYWNrIiksCiAgICAgICAgYXhpcy50ZXh0LnkgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50aWNrcy55ID0gZWxlbWVudF9ibGFuaygpKSArCiAgZ2d0aXRsZShwYXN0ZSgiUmVwYXJ0aXRpb24gb2YiLCBkaW0oY2V0YWNlYV9wYmRiKVsxXSwgInJlY29yZGVkIG9jY3VycmVuY2VzIHRocm91Z2ggdGltZSAtIFVuaWZvcm0gZHJhdyIpKQoKZ2dwbG90KGNldGFjZWFfcGJkYiwgYWVzKHg9LWFnZV9ydW5pZikpICsKICBnZW9tX2hpc3RvZ3JhbShiaW53aWR0aCA9IDEpICsKICBzY2FsZV94X2NvbnRpbnVvdXMobmFtZSA9ICJUaW1lIChNeSkiKSArCiAgc2NhbGVfeV9jb250aW51b3VzKG5hbWUgPSAiTnVtYmVyIG9mIG9jY3VycmVuY2VzIikgKwogIHNjYWxlX2ZpbGxfZGlzY3JldGUobmFtZT0iQWNjZXB0ZWQgcmFuayIpICsKICB0aGVtZShwYW5lbC5ncmlkLm1ham9yLnkgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgbGVnZW5kLnBvc2l0aW9uPSJib3R0b20iKSArCiAgZ2d0aXRsZShwYXN0ZSgiRXZvbHV0aW9uIG9mIHRoZSBudW1iZXIgb2NjdXJyZW5jZXMgdGhyb3VnaCB0aW1lICggdG90YWwgb2YiLCBkaW0oY2V0YWNlYV9wYmRiKVsxXSwgIikgLSBVbmlmb3JtIGRyYXciKSkKYGBgCgokXHRvJCBUaGUgZGlzdHJpYnV0aW9uIHNlZW1zIG11Y2ggc21vb3RoZXIgbm93LgoKIyMjIFVuaWZvcm0gc3Vic2FtcGxpbmcKClRoZXNlIG9jY3VycmVuY2VzIGFyZSB0b28gbnVtZXJvdXMgdG8gcGVyZm9ybSBhIHF1aWNrIHByZWxpbWluYXJ5IGFuYWx5c2lzLCBzbyBsZXQncyByYW5kb21seSBzdWJzYW1wbGUgYSBmcmFjdGlvbiBvZiB0aGVtLgoKYGBge3IsIGZpZy5hc3A9MC4zLCBmaWcud2lkdGg9OH0KY2V0YWNlYV9wYmRiX3N1YnNhbXBsZWQgPC0gc2FtcGxlX24oY2V0YWNlYV9wYmRiLCBzaXplPXJvdW5kKGxlbmd0aChhZ2VfcnVuaWYpKjAuMTApKQoKZ2dwbG90KGNldGFjZWFfcGJkYl9zdWJzYW1wbGVkLCBhZXMoeD0tYWdlX3J1bmlmLCB5PXJub3JtKGxlbmd0aChhZ2VfcnVuaWYpLCAxLCAwLjA1KSkpICsKICBnZW9tX3BvaW50KGNleD0wLjUsIGFscGhhPTAuNSkgKwogIHNjYWxlX3hfY29udGludW91cyhuYW1lID0gIlRpbWUgKE15KSIpICsKICBzY2FsZV95X2NvbnRpbnVvdXMobmFtZSA9ICJPY2N1cnJlbmNlcyIsIGxpbWl0cyA9IGMoMC43LCAxLjMpKSArCiAgc2NhbGVfZmlsbF9kaXNjcmV0ZShuYW1lPSJBY2NlcHRlZCByYW5rIikgKwogIHRoZW1lKHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy5saW5lLnggPSBlbGVtZW50X2xpbmUoc2l6ZSA9IDAuNSwgbGluZXR5cGUgPSAic29saWQiLCBjb2xvdXIgPSAiYmxhY2siKSwKICAgICAgICBheGlzLnRleHQueSA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLnRpY2tzLnkgPSBlbGVtZW50X2JsYW5rKCkpICsKICBnZ3RpdGxlKHBhc3RlKCJSZXBhcnRpdGlvbiBvZiIsIGRpbShjZXRhY2VhX3BiZGJfc3Vic2FtcGxlZClbMV0sICJyZWNvcmRlZCBvY2N1cnJlbmNlcyB0aHJvdWdoIHRpbWUgLSBVbmlmb3JtIGRyYXciKSkKCmdncGxvdChjZXRhY2VhX3BiZGJfc3Vic2FtcGxlZCwgYWVzKHg9LWFnZV9ydW5pZikpICsKICBnZW9tX2hpc3RvZ3JhbShiaW53aWR0aCA9IDEpICsKICBzY2FsZV94X2NvbnRpbnVvdXMobmFtZSA9ICJUaW1lIChNeSkiKSArCiAgc2NhbGVfeV9jb250aW51b3VzKG5hbWUgPSAiTnVtYmVyIG9mIG9jY3VycmVuY2VzIikgKwogIHNjYWxlX2ZpbGxfZGlzY3JldGUobmFtZT0iQWNjZXB0ZWQgcmFuayIpICsKICB0aGVtZShwYW5lbC5ncmlkLm1ham9yLnkgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgbGVnZW5kLnBvc2l0aW9uPSJib3R0b20iKSArCiAgZ2d0aXRsZShwYXN0ZSgiRXZvbHV0aW9uIG9mIHRoZSBudW1iZXIgb2NjdXJyZW5jZXMgdGhyb3VnaCB0aW1lICggdG90YWwgb2YiLCBkaW0oY2V0YWNlYV9wYmRiX3N1YnNhbXBsZWQpWzFdLCAiKSAtIFVuaWZvcm0gZHJhdyIpKQpgYGAKCiRcdG8kIFRoZSBkaXN0cmlidXRpb24gbG9va3Mgc2ltaWxhciwgd2l0aCBzb21lIG5vaXNlIGR1ZSB0byBoaWdoZXIgdmFyaWFuY2Ugd2l0aCBzbWFsbGVyIHNhbXBsZS4KCmBgYHtyfQp3cml0ZShjZXRhY2VhX3BiZGIkYWdlX21lYW4sIGZpbGUgPSAiLi4vZGF0YS1jZXRhY2VhbnMvQ2V0YWNlYV9vY2N1cnJlbmNlc19tZWFuX2FnZS5jc3YiLCBzZXA9IjsgIiwgbmNvbHVtbnMgPSBkaW0oY2V0YWNlYV9wYmRiKVsxXSkKd3JpdGUoY2V0YWNlYV9wYmRiJGFnZV9ydW5pZiwgZmlsZSA9ICIuLi9kYXRhLWNldGFjZWFucy9DZXRhY2VhX2FnZV9ydW5pZl9hZ2UuY3N2Iiwgc2VwPSI7ICIsIG5jb2x1bW5zID0gZGltKGNldGFjZWFfcGJkYilbMV0pCndyaXRlKGNldGFjZWFfcGJkYl9zdWJzYW1wbGVkJGFnZV9ydW5pZiwgZmlsZSA9ICIuLi9kYXRhLWNldGFjZWFucy9DZXRhY2VhX2FnZV9ydW5pZl9hZ2Vfc3Vic2FtcGxlZC5jc3YiLCBzZXA9IjsgIiwgbmNvbHVtbnMgPSBkaW0oY2V0YWNlYV9wYmRiX3N1YnNhbXBsZWQpWzFdKQpgYGAKCiMjIFJlcGFydGl0aW9uIGFtb25nIGFjY2VwdGVkIHJhbmtzCgpPY2N1cnJlbmNlcyBhcmUgYXNzb2NpYXRlZCB3aXRoIGFuICoqYWNjZXB0ZWQgcmFuayoqLCBkZXBlbmRpbmcgb24gdGhlIGxldmVsIG9mIGRldGFpbCBvZiB0aGVpciBkZXNjcmlwdGlvbiBhbmQgYXR0cmlidXRpb24gdG8gYSBnaXZlbiB0YXhvbm9taWMgcG9zaXRpb24uCgojIyMgUGllIGNoYXJ0CgpgYGB7ciwgZmlnLndpZHRoPTV9CmdncGxvdChjZXRhY2VhX3BiZGIsIGFlcyh4PWZhY3RvcihyZWNvcmRfdHlwZSksIGZpbGw9YWNjZXB0ZWRfcmFuaykpICsKICBnZW9tX2Jhcih3aWR0aCA9IDEsIHN0YXQgPSAiY291bnQiKSArCiAgY29vcmRfcG9sYXIoInkiKSArIAogIHNjYWxlX2ZpbGxfZGlzY3JldGUobmFtZT0iQWNjZXB0ZWQgcmFuayIpICsKICBsYWJzKHggPSBOVUxMLCB5ID0gTlVMTCwgZmlsbCA9IE5VTEwsIHRpdGxlID0gIlJlcGFydGl0aW9uIG9mIG9jY3VycmVuY2VzIGFtb25nIGFjY2VwdGVkIHJhbmtzIikKYGBgCgokXHRvJCBIYWxmIG9mIHRoZSBvY2N1cnJlbmNlcyBhcmUgaWRlbnRpZmllZCBhdCB0aGUgbGV2ZWwgb2YgdGhlIHNwZWNpZXMgYW5kIDEvMyBhdCB0aGUgZ2VudXMgb3IgZmFtaWx5LgoKU29tZSBjbGFkZXMgYXJlIHVucmFua2VkOgoKYGBge3J9CnRhYmxlKGFzLmNoYXJhY3RlcihjZXRhY2VhX3BiZGJbY2V0YWNlYV9wYmRiJGFjY2VwdGVkX3Jhbms9PSJ1bnJhbmtlZCBjbGFkZSIsXSRhY2NlcHRlZF9uYW1lKSkKYGBgCgojIyMgVGltZSByZXBhcnRpdGlvbiBieSByYW5rCgpgYGB7ciwgZmlnLmFzcD0wLjQsIGZpZy53aWR0aD0xMH0KZ2dwbG90KGNldGFjZWFfcGJkYltjZXRhY2VhX3BiZGIkYWNjZXB0ZWRfcmFuayAlaW4lIGMoInNwZWNpZXMiLCAiZ2VudXMiKSxdLCBhZXMoeD0tYWdlX3J1bmlmLCBmaWxsPWFjY2VwdGVkX3JhbmspKSArCiAgZ2VvbV9oaXN0b2dyYW0oYmlud2lkdGggPSAwLjEpICsKICBzY2FsZV94X2NvbnRpbnVvdXMobmFtZSA9ICJUaW1lIChNeSkiKSArCiAgc2NhbGVfeV9jb250aW51b3VzKG5hbWUgPSAiTnVtYmVyIG9mIG9jY3VycmVuY2VzIikgKwogIHNjYWxlX2ZpbGxfZGlzY3JldGUobmFtZT0iQWNjZXB0ZWQgcmFuayIpICsKICB0aGVtZShwYW5lbC5ncmlkLm1ham9yLnkgPSBlbGVtZW50X2JsYW5rKCkpICsKICBnZ3RpdGxlKCJFdm9sdXRpb24gb2YgdGhlIG51bWJlciBvY2N1cnJlbmNlcyB0aHJvdWdoIHRpbWUgKDAuMSBNeSB0aW1lIGJpbnMpLCBieSBhY2NlcHRlZCByYW5rIikgKwogIGZhY2V0X2dyaWQoYWNjZXB0ZWRfcmFuayB+IC4sIHNjYWxlcz0iZnJlZSIpCmBgYAoKJFx0byQgQW4gYXBwYXJlbnQgaHVnZSBjbHVzdGVyIG9mIG9jY3VycmVuY2VzIGFwcGVhcnMgaW4gcmVjZW50IHRpbWVzLCB3aXRoIHZlcnkgcHJlY2lzZSBkYXRpbmcgPSBBcnRpZmFjdCBkdWUgdG8gdGhlICJQdWxsIG9mIHRoZSBSZWNlbnQiIGVmZmVjdCA/IEJvbmVzIGNvbGxlY3RlZCBieSBhbmNpZW50IGhvbWluaWRzID8KCiRcaW1wbGllcyQgVGhlc2Ugb2NjdXJyZW5jZXMgc2VlbSB0byBvYmV5IHRvIGEgY29tcGxldGVseSBkaWZmZXJlbnQgcHJvY2VzcyBhbmQgb3ZlciBhIHZlcnkgc2hvcnQgcGVyaW9kIG9mIHRpbWUsIHNvIHdlIGRlY2lkZWQgdG8gKipyZW1vdmUgYWxsIExhdGUgUGxlaXN0b2NlbmUgYW5kIEhvbG9jZW5lIG9jY3VycmVuY2VzKiogaW4gb3JkZXIgdG8gYXZvaWQgdGhpcyBiaWFzLgoKIyMjIEJJQVMgQ09SUkVDVElPTiBOwrAxOiBSZW1vdmUgYWxsIExhdGUgUGxlaXN0b2NlbmUgYW5kIEhvbG9jZW5lIG9jY3VycmVuY2VzCgpgYGB7cn0KQ2V0YWNlYV9vY2MgPC0gY2V0YWNlYV9wYmRiW2NldGFjZWFfcGJkYiRhZ2VfcnVuaWYgPiAwLjEyNixdCgpkYXRhLmZyYW1lKGNldGFjZWFfcGJkYiA9IGRpbShjZXRhY2VhX3BiZGIpWzFdLAogICAgICAgICAgIENldGFjZWFfb2NjID0gZGltKENldGFjZWFfb2NjKVsxXSwKICAgICAgICAgICByZW1vdmVkID0gZGltKGNldGFjZWFfcGJkYilbMV0tZGltKENldGFjZWFfb2NjKVsxXSwKICAgICAgICAgICByb3cubmFtZXMgPSAiTnVtYmVyIG9mIG9jY3VycmVuY2VzIikKYGBgCgpgYGB7ciBmaWcuaGVpZ2h0PTZ9CmdncGxvdChDZXRhY2VhX29jY1shQ2V0YWNlYV9vY2MkYWNjZXB0ZWRfcmFuayAlaW4lIGMoInN1YnNwZWNpZXMiLCAiaW5mcmFvcmRlciIpLF0sIGFlcyh4PS1hZ2VfcnVuaWYsIGZpbGw9YWNjZXB0ZWRfcmFuaykpICsKICBnZW9tX2hpc3RvZ3JhbShiaW53aWR0aCA9IDAuNSkgKwogIHNjYWxlX3hfY29udGludW91cyhuYW1lID0gIlRpbWUgKE15KSIpICsKICBzY2FsZV95X2NvbnRpbnVvdXMobmFtZSA9ICJOdW1iZXIgb2Ygb2NjdXJyZW5jZXMiKSArCiAgc2NhbGVfZmlsbF9kaXNjcmV0ZShuYW1lPSJBY2NlcHRlZCByYW5rIikgKwogIHRoZW1lKHBhbmVsLmdyaWQubWFqb3IueSA9IGVsZW1lbnRfYmxhbmsoKSkgKwogIGdndGl0bGUoIkV2b2x1dGlvbiBvZiB0aGUgbnVtYmVyIG9jY3VycmVuY2VzIHRocm91Z2ggdGltZSAoMC41IE15IHRpbWUgYmlucyksIGJ5IGFjY2VwdGVkIHJhbmsiKSArCiAgZmFjZXRfZ3JpZChhY2NlcHRlZF9yYW5rIH4gLiwgc2NhbGVzPSJmcmVlIikKYGBgCgokXHRvJCBUaGUgZGlzdHJpYnV0aW9ucyBhcmUgbXVjaCBtb3JlIGhvbW9nZW5lb3VzIGFmdGVyIHRoZSBjb3JyZWN0aW9uLiBTaW1pbGFyIHRyZW5kcyBjYW4gYmUgb2JzZXJ2ZWQgYXQgZWFjaCByYW5rLCB3aXRoIHBlYWtzIGF0IH4xNU15IGFuZCB+NU15LgoKIyMjIFJlZHVuZGFuY3kgb2Ygb2NjdXJyZW5jZXMgd2l0aCB0aGUgc2FtZSBhY2NlcHRlZCBuYW1lCgpgYGB7ciwgZmlnLmFzcD0wLjQsIGZpZy53aWR0aD0xMH0KZ2dwbG90KGNldGFjZWFfcGJkYiwgYWVzKHg9cmVvcmRlcihhY2NlcHRlZF9uYW1lLCB0YWJsZShhY2NlcHRlZF9uYW1lKVthY2NlcHRlZF9uYW1lXSksIGZpbGw9YWNjZXB0ZWRfcmFuaykpICsKICBnZW9tX2JhcihzdGF0PSJjb3VudCIpICsgCiAgc2NhbGVfeF9kaXNjcmV0ZShuYW1lID0gIkFjY2VwdGVkIG5hbWVzIikgKwogIHNjYWxlX3lfY29udGludW91cyh0cmFucyA9ICJsb2cxMCIsIG5hbWUgPSAiTnVtYmVyIG9mIGNvcnJlc3BvbmRpbmcgb2NjdXJyZW5jZXMgKGxvZy1zY2FsZSkiKSArCiAgc2NhbGVfZmlsbF9kaXNjcmV0ZShuYW1lPSJBY2NlcHRlZCByYW5rIikgKwogIHRoZW1lKGF4aXMudGV4dC54PWVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLnRpY2tzLng9ZWxlbWVudF9ibGFuaygpLAogICAgICAgIHBhbmVsLmdyaWQubWFqb3IueCA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpICsKICBnZ3RpdGxlKCJEaXN0cmlidXRpb25zIG9mIHRoZSBudW1iZXIgb2Ygb2NjdXJyZW5jZXMgd2l0aCB0aGUgc2FtZSBhY2NlcHRlZCBuYW1lLCBieSBhY2NlcHRlZCByYW5rIikgKwogIGZhY2V0X2dyaWQoLiB+IGFjY2VwdGVkX3JhbmssIHNjYWxlcz0iZnJlZV94IikKYGBgCgokXHRvJCB+SGFsZiBvZiBzcGVjaWVzL2dlbmVyYS9zdWJmYW1pbGllcyBoYXZlIG9ubHkgb25lIHNwZWNpbWVuIGJ5IGFjY2VwdGVkIG5hbWUsIGJ1dCBpdCBjb3VsZCBnbyB1cCB0byB+NTAgd2l0aGluIHRoZSBzYW1lIHNwZWNpZXMgYW5kIH4yMDAgb2NjdXJyZW5jZXMgd2l0aGluIHRoZSBzYW1lIHN1Ym9yZGVyLiAqKkluIG91ciBtb2RlbCBhbGwgc3BlY2llcyBhcmUgdXBwb3NlZCB0byBoYXZlIHRoZSBzYW1lIGFidW5kYW5jZSAoaWRlbnRpY2FsIHNhbXBsaW5nIHJhdGVzIGFtb25nIGJyYW5jaGVzKSwgc28gdGhvc2UgaHVnZSBkaWZmZXJlbmNlcyB3aWxsIGhhdmUgdG8gYmUgbWl0aWdhdGVkLioqIFNlZSBsYXRlciBmb3IgYSBxdWFudGlmaWNhdGlvbiBvZiB0aGlzIGRpc2NyZXBhbmN5IGFuZCBhIGNvbXBhcmlzb24gd2l0aCBvdXIgbW9kZWwncyBhc3N1bXB0aW9ucwoKJFxpbXBsaWVzJCBPdXIgZ29hbCBub3cgd2lsbCBiZSB0byBjb3JyZWN0IHRoaXMgYWJ1bmRhbmNlIGJpYXMuCgojIE1pdGlnYXRlIHRoZSBhYnVuZGFuY2UgYmlhcwoKVG8gcXVhbnRpZnkgbW9yZSBwcmVjaXNlbHkgdGhpcyBiaWFzLCB3ZSB3aWxsOgoKICAxLiBDb3VudCB0aGUgKipudW1iZXIgb2Ygb2NjdXJyZW5jZXMqKiBmb3IgZWFjaCB0YXhvbgogIDIuIE9idGFpbiB0aGUgKipzdHJhdGlncmFwaGljIHJhbmdlKiogb2YgZWFjaCB0YXhhIC0gaWUuIHRoZSB0aW1lIGludGVydmFsIGluIHdoaWNoIGEgdGF4b24gaXMgb2JzZXJ2ZWQgLSBieSBjb21iaW5pbmcgdGhlIHN0cmF0aWdyYXBoaWMgYWdlIHVuY2VydGFpbnRpZXMgb2YgaXRzIG9jY3VycmVuY2VzCiAgMy4gQ29tcHV0ZSB0aGUgKipkZW5zaXR5IG9mIG9jY3VycmVuY2VzKiogPSBuYiBvZiBvY2N1cnJlbmNlcyAvIHN0cmF0aWdyYXBoaWMgcmFuZ2UsIGV4cHJlc3NlZCBpbiAibnVtYmVyIG9mIG9jY3VycmVuY2VzIGJ5IG1pbGxpb24geWVhcnMiCgojIyBDb21wdXRlIHRoZSBvY2N1cnJlbmNlIGRlbnNpdHkKIyMjIENvdW50IG9jY3VycmVuY2VzIGJ5IGFjY2VwdGVkIG5hbWUKCkNvdW50IHRoZSBudW1iZXIgb2Ygb2NjdXJyZW5jZXMgd2l0aCB0aGUgc2FtZSBhY2NlcHRlZCBuYW1lIGFuZCBwbG90IHRoZWlyIGRpc3RyaWJ1dGlvbi4KCmBgYHtyIGZpZy5hc3A9MC41LCBmaWcud2lkdGg9MTB9CiMgQ291bnQgdGhlIG51bWJlciBvZiBvY2N1cnJlbmNlcyB3aXRoIHRoZSBzYW1lIGFjY2VwdGVkIG5hbWUKQ2V0YWNlYV9vY2MkYWNjZXB0ZWRfbmFtZV9jb3VudCA8LSBzYXBwbHkoQ2V0YWNlYV9vY2MkYWNjZXB0ZWRfbmFtZSwgZnVuY3Rpb24oeCl7dGFibGUoQ2V0YWNlYV9vY2MkYWNjZXB0ZWRfbmFtZSlbeF19KQoKbXlfYnJlYWtzIDwtIGMoMSwzLDEwLDM1LDEwMCxtYXgoQ2V0YWNlYV9vY2MkYWNjZXB0ZWRfbmFtZV9jb3VudCkpCgojIGdncGxvdChDZXRhY2VhX29jY1shKENldGFjZWFfb2NjJGFjY2VwdGVkX3JhbmsgJWluJSBjKCJzcGVjaWVzIiwgImdlbnVzIiwgImZhbWlseSIpKSxdLCBhZXMoeD0tbWF4X21hLCB5PWFjY2VwdGVkX25hbWUpKSArCiMgICBnZW9tX3NlZ21lbnQoYWVzKHggPSAtbWF4X21hLCB5ID0gcmVvcmRlcihhY2NlcHRlZF9uYW1lLCAtYWdlX21lYW4pLCB4ZW5kID0gLW1pbl9tYSwgeWVuZD1yZW9yZGVyKGFjY2VwdGVkX25hbWUsIC1hZ2VfbWVhbiksIGNvbG9yPWFjY2VwdGVkX25hbWVfY291bnQpLCBhcnJvdz1hcnJvdyhlbmRzID0gImJvdGgiLCBhbmdsZT05MCwgbGVuZ3RoID0gdW5pdCgxLCAibW0iKSksIGFscGhhPTAuNSkgKwojICAgZ2VvbV9wb2ludChhZXMoeD0tYWdlX3J1bmlmKSwgY29sPSJyZWQiLCBjZXg9MSwgYWxwaGE9MC4zKSArCiMgICBzY2FsZV94X2NvbnRpbnVvdXMobmFtZSA9ICJUaW1lIChNeSkiKSArCiMgICBzY2FsZV95X2Rpc2NyZXRlKG5hbWUgPSAiQWNjZXB0ZWQgcmFua3MiKSArCiMgICBsYWJzKGNvbG91cj0iQWNjZXB0ZWQgbmFtZXMgY291bnQiKSArCiMgICB0aGVtZShwYW5lbC5ncmlkLm1ham9yLnkgPSBlbGVtZW50X2JsYW5rKCkpICsKIyAgIHNjYWxlX2NvbG9yX2dyYWRpZW50bihjb2xvdXJzID0gYygiZGFya2JsdWUiLCAiZm9yZXN0Z3JlZW4iLCAiYmxhY2siKSwgdHJhbnM9ImxvZyIsIGJyZWFrcz1teV9icmVha3MsIGxhYmVscz1teV9icmVha3MpICsgCiMgICBnZ3RpdGxlKCJEaXN0cmlidXRpb25zIG9mIGZvc3NpbCBhZ2UgdW5jZXJ0YWludGllcywgYnkgYWNjZXB0ZWQgcmFuayIpICsKIyAgIGZhY2V0X2dyaWQoYWNjZXB0ZWRfcmFuayB+IC4sIHNjYWxlcyA9ICJmcmVlIikKCmdncGxvdChDZXRhY2VhX29jY1tDZXRhY2VhX29jYyRhY2NlcHRlZF9yYW5rID09InNwZWNpZXMiLF0sIGFlcyh4PS1tYXhfbWEsIHk9YWNjZXB0ZWRfbmFtZSkpICsKICBnZW9tX3NlZ21lbnQoYWVzKHggPSAtbWF4X21hLCB5ID0gcmVvcmRlcihhY2NlcHRlZF9uYW1lLCAtYWdlX21lYW4pLCB4ZW5kID0gLW1pbl9tYSwgeWVuZD1yZW9yZGVyKGFjY2VwdGVkX25hbWUsIC1hZ2VfbWVhbiksIGNvbG9yPWFjY2VwdGVkX25hbWVfY291bnQpLCBhcnJvdz1hcnJvdyhlbmRzID0gImJvdGgiLCBhbmdsZT05MCwgbGVuZ3RoID0gdW5pdCgxLCAibW0iKSksIGFscGhhPTAuNSkgKwogIGdlb21fcG9pbnQoYWVzKHg9LWFnZV9ydW5pZiksIGNvbD0icmVkIiwgY2V4PTEsIGFscGhhPTAuMykgKwogIHNjYWxlX3hfY29udGludW91cyhuYW1lID0gIlRpbWUgKE15KSIpICsKICBzY2FsZV95X2Rpc2NyZXRlKG5hbWUgPSAiU3BlY2llcyIpICsKICBsYWJzKGNvbG91cj0iTmIgb2Ygb2NjdXJyZW5jZXMiKSArCiAgdGhlbWUocGFuZWwuZ3JpZC5tYWpvci55ID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIGF4aXMudGV4dC55PWVsZW1lbnRfdGV4dChzaXplPTIpKSArCiAgc2NhbGVfY29sb3JfZ3JhZGllbnRuKGNvbG91cnMgPSBjKCJkYXJrYmx1ZSIsICJmb3Jlc3RncmVlbiIsICJibGFjayIpLCB0cmFucz0ibG9nIiwgYnJlYWtzPW15X2JyZWFrcywgbGFiZWxzPW15X2JyZWFrcykgKyAKICBnZ3RpdGxlKCJEaXN0cmlidXRpb25zIG9mIGZvc3NpbCBhZ2UgdW5jZXJ0YWludGllcyBmb3IgYWxsIHNwZWNpZXMiKSArCiAgZmFjZXRfZ3JpZChhY2NlcHRlZF9yYW5rIH4gLiwgc2NhbGVzID0gImZyZWUiKQoKZ2dwbG90KENldGFjZWFfb2NjW0NldGFjZWFfb2NjJGFjY2VwdGVkX3JhbmsgPT0iZ2VudXMiLF0sIGFlcyh4PS1tYXhfbWEsIHk9YWNjZXB0ZWRfbmFtZSkpICsKICBnZW9tX3NlZ21lbnQoYWVzKHggPSAtbWF4X21hLCB5ID0gcmVvcmRlcihhY2NlcHRlZF9uYW1lLCAtYWdlX21lYW4pLCB4ZW5kID0gLW1pbl9tYSwgeWVuZD1yZW9yZGVyKGFjY2VwdGVkX25hbWUsIC1hZ2VfbWVhbiksIGNvbG9yPWFjY2VwdGVkX25hbWVfY291bnQpLCBhcnJvdz1hcnJvdyhlbmRzID0gImJvdGgiLCBhbmdsZT05MCwgbGVuZ3RoID0gdW5pdCgxLCAibW0iKSksIGFscGhhPTAuNSkgKwogIGdlb21fcG9pbnQoYWVzKHg9LWFnZV9ydW5pZiksIGNvbD0icmVkIiwgY2V4PTEsIGFscGhhPTAuMykgKwogIHNjYWxlX3hfY29udGludW91cyhuYW1lID0gIlRpbWUgKE15KSIpICsKICBzY2FsZV95X2Rpc2NyZXRlKG5hbWUgPSAiR2VudXMiKSArCiAgbGFicyhjb2xvdXI9IkFjY2VwdGVkIG5hbWVzIGNvdW50IikgKwogIHRoZW1lKHBhbmVsLmdyaWQubWFqb3IueSA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLnRleHQueT1lbGVtZW50X3RleHQoc2l6ZT02KSkgKwogIHNjYWxlX2NvbG9yX2dyYWRpZW50bihjb2xvdXJzID0gYygiZGFya2JsdWUiLCAiZm9yZXN0Z3JlZW4iLCAiYmxhY2siKSwgdHJhbnM9ImxvZyIsIGJyZWFrcz1teV9icmVha3MsIGxhYmVscz1teV9icmVha3MpICsKICBnZ3RpdGxlKCJEaXN0cmlidXRpb25zIG9mIGZvc3NpbCBhZ2UgdW5jZXJ0YWludGllcyBmb3IgYWxsIGdlbmVyYSIpICsKICBmYWNldF9ncmlkKGFjY2VwdGVkX3JhbmsgfiAuLCBzY2FsZXMgPSAiZnJlZSIpCgojIGdncGxvdChDZXRhY2VhX29jY1tDZXRhY2VhX29jYyRhY2NlcHRlZF9yYW5rID09ImZhbWlseSIsXSwgYWVzKHg9LW1heF9tYSwgeT1hY2NlcHRlZF9uYW1lKSkgKwojICAgZ2VvbV9zZWdtZW50KGFlcyh4ID0gLW1heF9tYSwgeSA9IHJlb3JkZXIoYWNjZXB0ZWRfbmFtZSwgLWFnZV9tZWFuKSwgeGVuZCA9IC1taW5fbWEsIHllbmQ9cmVvcmRlcihhY2NlcHRlZF9uYW1lLCAtYWdlX21lYW4pLCBjb2xvcj1hY2NlcHRlZF9uYW1lX2NvdW50KSwgYXJyb3c9YXJyb3coZW5kcyA9ICJib3RoIiwgYW5nbGU9OTAsIGxlbmd0aCA9IHVuaXQoMSwgIm1tIikpLCBhbHBoYT0wLjUpICsKIyAgIGdlb21fcG9pbnQoYWVzKHg9LWFnZV9ydW5pZiksIGNvbD0icmVkIiwgY2V4PTEsIGFscGhhPTAuMykgKwojICAgc2NhbGVfeF9jb250aW51b3VzKG5hbWUgPSAiVGltZSAoTXkpIikgKwojICAgc2NhbGVfeV9kaXNjcmV0ZShuYW1lID0gIkdlbnVzIikgKwojICAgbGFicyhjb2xvdXI9IkFjY2VwdGVkIG5hbWVzIGNvdW50IikgKwojICAgdGhlbWUocGFuZWwuZ3JpZC5tYWpvci55ID0gZWxlbWVudF9ibGFuaygpKSArCiMgICBzY2FsZV9jb2xvcl9ncmFkaWVudG4oY29sb3VycyA9IGMoImRhcmtibHVlIiwgImZvcmVzdGdyZWVuIiwgImJsYWNrIiksIHRyYW5zPSJsb2ciLCBicmVha3M9bXlfYnJlYWtzLCBsYWJlbHM9bXlfYnJlYWtzKSArIAojICAgZ2d0aXRsZSgiRGlzdHJpYnV0aW9ucyBvZiBmb3NzaWwgYWdlIHVuY2VydGFpbnRpZXMgKGZhbWlsaWVzKSIpICsKIyAgIGZhY2V0X2dyaWQoYWNjZXB0ZWRfcmFuayB+IC4sIHNjYWxlcyA9ICJmcmVlIikKYGBgCgokXHRvJCBTb21lIG9jY3VycmVuY2VzIGhhdmUgdG9vIG11Y2ggYWdlIHVuY2VydGFpbnR5ICh1bnJlbGF0ZWQgdG8gdGF4b24gbG9uZ2V2aXR5IGluIGV4dHJlbWUgY2FzZXMgbGlrZSB0aGUgb25lIHNwYW5uaW5nIDYwTXkpLCB0aGV5IHJpc2sgdG8gYXJ0aWZpY2lhbGx5IGluY3JlYXNlIHNwZWNpZXMgZHVyYXRpb24uCgojIyMgQklBUyBDT1JSRUNUSU9OIE7CsDI6IEV4Y2x1ZGUgb2NjdXJyZW5jZXMgd2l0aCBoaWdobHkgdW5jZXJ0YWluIGRhdGluZyAoPiAxME15KQoKYGBge3IsIGZpZy5hc3A9MC40LCBmaWcud2lkdGg9MTB9CiMgR2V0IHRoZSBkdXJhdGlvbiBvZiB0aGUgdW5jZXJ0YWludHkgaW50ZXJ2YWxzCkNldGFjZWFfb2NjJGFnZV91bmNlcnRhaW50eSA8LSBDZXRhY2VhX29jYyRtYXhfbWEtQ2V0YWNlYV9vY2MkbWluX21hCgpnZ3Bsb3QoQ2V0YWNlYV9vY2MsIGFlcyh4PWFnZV91bmNlcnRhaW50eSwgZmlsbD1hY2NlcHRlZF9yYW5rKSkgKwogIGdlb21faGlzdG9ncmFtKGJpbndpZHRoID0gMSkgKwogIHNjYWxlX3hfY29udGludW91cyhuYW1lID0gIkFnZSB1bmNlcnRhaW50eSAoTXkpIikgKwogIHNjYWxlX3lfY29udGludW91cyhuYW1lID0gIk51bWJlciBvZiBjb3JyZXNwb25kaW5nIG9jY3VycmVuY2VzIikgKwogIGdlb21fc2VnbWVudChhZXMoeCA9IDkuNSwgeSA9IDAsIHhlbmQgPSA5LjUsIHllbmQ9MTA1MCksIGNvbG9yPSJibGFjayIsIGxpbmV0eXBlPSJkYXNoZWQiKSArCiAgZ2d0aXRsZSgiRGlzdHJpYnV0aW9uIG9mIG9jY3VycmVuY2VzJyBhZ2UgdW5jZXJ0YWludHkgYW5kIHJlbW92YWwgbGltaXQgKGRhc2hlZCBsaW5lKSIpCmBgYAoKTW9zdCBvZiBvY2N1cnJlbmNlcyBzaG93IGxlc3MgdGhhbiAxMCBNeSBhZ2UgdW5jZXJ0YWludHksIGxldCdzIGtlZXAgb25seSB0aGVzZSBvbmVzLgoKYGBge3J9CmRhdGEuZnJhbWUoYWxsX3JhbmdlcyA9IGRpbShDZXRhY2VhX29jYylbMV0sCiAgICAgICAgICAgc21hbGxlcl8xME15ID0gZGltKENldGFjZWFfb2NjW0NldGFjZWFfb2NjJGFnZV91bmNlcnRhaW50eTwxMCxdKVsxXSwKICAgICAgICAgICByZW1vdmVkID0gZGltKENldGFjZWFfb2NjKVsxXS1kaW0oQ2V0YWNlYV9vY2NbQ2V0YWNlYV9vY2MkYWdlX3VuY2VydGFpbnR5PDEwLF0pWzFdLCByb3cubmFtZXMgPSAiTnVtYmVyIG9mIG9jY3VycmVuY2VzIikKYGBgCgpgYGB7ciBmaWcuaGVpZ2h0PTZ9CiMgZ2dwbG90KENldGFjZWFfb2NjLCBhZXMoeD1hZ2VfcnVuaWYsIHk9YWdlX3VuY2VydGFpbnR5KSkgKwojICAgZ2VvbV9wb2ludChhbHBoYT0wLjA1KSArCiMgICBzY2FsZV94X2NvbnRpbnVvdXMobmFtZSA9ICJVbmlmb3JtbHkgZHJhd24gYWdlIChNeSkiKSArCiMgICBzY2FsZV95X2NvbnRpbnVvdXMobmFtZSA9ICJBZ2UgdW5jZXJ0YWludHkgKE15KSIpICsKIyAgIGdndGl0bGUoIkRpc3RyaWJ1dGlvbiBvZiBvY2N1cnJlbmNlcycgYWdlIHVuY2VydGFpbnR5IikKCmdncGxvdChDZXRhY2VhX29jY1tDZXRhY2VhX29jYyRhZ2VfdW5jZXJ0YWludHkgIT0gNjMuNDEyLF0sIGFlcyh4PWFnZV9ydW5pZiwgeT1hZ2VfdW5jZXJ0YWludHkpKSArCiAgZ2VvbV9wb2ludChhbHBoYT0wLjA1KSArCiAgc2NhbGVfeF9jb250aW51b3VzKG5hbWUgPSAiVW5pZm9ybWx5IGRyYXduIGFnZSAoTXkpIikgKwogIHNjYWxlX3lfY29udGludW91cyhuYW1lID0gIkFnZSB1bmNlcnRhaW50eSAoTXkpIikgKwogIGdlb21fc2VnbWVudChhZXMoeCA9IDAsIHkgPSAxMCwgeGVuZD02MCwgeWVuZCA9IDEwKSwgY29sb3I9ImJsYWNrIiwgbGluZXR5cGU9ImRhc2hlZCIpICsKICBnZ3RpdGxlKCJEaXN0cmlidXRpb24gb2Ygb2NjdXJyZW5jZXMnIGFnZSB1bmNlcnRhaW50eSBhbmQgcmVtb3ZhbCBsaW1pdCAoZGFzaGVkIGxpbmUpIikKCiMgZ2dwbG90KENldGFjZWFfb2NjW0NldGFjZWFfb2NjJGFnZV91bmNlcnRhaW50eTwxMCxdLCBhZXMoeD1hZ2VfcnVuaWYsIHk9YWdlX3VuY2VydGFpbnR5KSkgKwojICAgZ2VvbV9wb2ludChhbHBoYT0wLjA1KSArCiMgICBzY2FsZV94X2NvbnRpbnVvdXMobmFtZSA9ICJVbmlmb3JtbHkgZHJhd24gYWdlIChNeSkiKSArCiMgICBzY2FsZV95X2NvbnRpbnVvdXMobmFtZSA9ICJBZ2UgdW5jZXJ0YWludHkgKE15KSIpICsKIyAgIGdndGl0bGUoIkRpc3RyaWJ1dGlvbiBvZiBvY2N1cnJlbmNlcycgYWdlIHVuY2VydGFpbnR5IikKCmhpc3QoLUNldGFjZWFfb2NjJGFnZV9ydW5pZiwgYnJlYWtzID0gNTAsIGNvbD0icmVkIiwgcHJvYmFiaWxpdHk9VCwgbWFpbj0iRGlzdHJpYnV0aW9uIG9mIG9jY3VycmVuY2VzLCB3aXRoIChyZWQpIG9mIHdpdGhvdXQgKGJsdWUpIHJlY2VudCBzYW1wbGVzIiwgeGxhYiA9ICJUaW1lIChNeSkiLCB5bGFiID0gIlByb3BvcnRpb24gb2Ygb2NjdXJyZW5jZXMiKQpoaXN0KC1DZXRhY2VhX29jY1tDZXRhY2VhX29jYyRhZ2VfdW5jZXJ0YWludHk8MTAsXSRhZ2VfcnVuaWYsIGJyZWFrcyA9IDUwLCBjb2w9ImJsdWUiLCBwcm9iYWJpbGl0eT1ULCBkZW5zaXR5PVQsIGFkZD1UKQpgYGAKCiRcdG8kIFRoZSByZW1vdmFsIG9mIGhpZ2hseSB1bmNlcnRhaW4gb2NjdXJyZW5jZXMgc2VlbXMgdG8gYmUgb25seSBhIGxpdHRsZSBiaWFzZWQsIGV2ZW4gaWYgdW5jZXJ0YWludHkgZ2xvYmFsbHkgaW5jcmVhc2VzIHdpdGggYWdlLgoKYGBge3IsIGZpZy5hc3A9MC41LCBmaWcud2lkdGg9MTB9Cm15X2JyZWFrcyA8LSBjKDEsMywxMCwzNSwxMDAsbWF4KENldGFjZWFfb2NjJGFjY2VwdGVkX25hbWVfY291bnQpKQoKIyBnZ3Bsb3QoQ2V0YWNlYV9vY2NbIShDZXRhY2VhX29jYyRhY2NlcHRlZF9yYW5rICVpbiUgYygic3BlY2llcyIsICJnZW51cyIsICJmYW1pbHkiKSkgJiBDZXRhY2VhX29jYyRhZ2VfdW5jZXJ0YWludHk8MTAsXSwgYWVzKHg9LW1heF9tYSwgeT1hY2NlcHRlZF9uYW1lKSkgKwojICAgZ2VvbV9zZWdtZW50KGFlcyh4ID0gLW1heF9tYSwgeSA9IHJlb3JkZXIoYWNjZXB0ZWRfbmFtZSwgLWFnZV9tZWFuKSwgeGVuZCA9IC1taW5fbWEsIHllbmQ9cmVvcmRlcihhY2NlcHRlZF9uYW1lLCAtYWdlX21lYW4pLCBjb2xvcj1hY2NlcHRlZF9uYW1lX2NvdW50KSwgYXJyb3c9YXJyb3coZW5kcyA9ICJib3RoIiwgYW5nbGU9OTAsIGxlbmd0aCA9IHVuaXQoMSwgIm1tIikpLCBhbHBoYT0wLjUpICsKIyAgIGdlb21fcG9pbnQoYWVzKHg9LWFnZV9ydW5pZiksIGNvbD0icmVkIiwgY2V4PTEsIGFscGhhPTAuNSkgKwojICAgc2NhbGVfeF9jb250aW51b3VzKG5hbWUgPSAiVGltZSAoTXkpIikgKwojICAgc2NhbGVfeV9kaXNjcmV0ZShuYW1lID0gIkFjY2VwdGVkIHJhbmtzIikgKwojICAgbGFicyhjb2xvdXI9IkFjY2VwdGVkIG5hbWVzIGNvdW50IikgKwojICAgdGhlbWUocGFuZWwuZ3JpZC5tYWpvci55ID0gZWxlbWVudF9ibGFuaygpKSArCiMgICBzY2FsZV9jb2xvcl9ncmFkaWVudG4oY29sb3VycyA9IGMoImRhcmtibHVlIiwgImZvcmVzdGdyZWVuIiwgImJsYWNrIiksIHRyYW5zPSJsb2ciLCBicmVha3M9bXlfYnJlYWtzLCBsYWJlbHM9bXlfYnJlYWtzKSArIAojICAgZ2d0aXRsZSgiRGlzdHJpYnV0aW9ucyBvZiBmb3NzaWwgYWdlIHVuY2VydGFpbnRpZXMsIGJ5IGFjY2VwdGVkIHJhbmsiKSArCiMgICBmYWNldF9ncmlkKGFjY2VwdGVkX3JhbmsgfiAuLCBzY2FsZXMgPSAiZnJlZSIpCgpnZ3Bsb3QoQ2V0YWNlYV9vY2NbQ2V0YWNlYV9vY2MkYWNjZXB0ZWRfcmFuayA9PSJzcGVjaWVzIiAmIENldGFjZWFfb2NjJGFnZV91bmNlcnRhaW50eTwxMCxdLCBhZXMoeD0tbWF4X21hLCB5PWFjY2VwdGVkX25hbWUpKSArCiAgZ2VvbV9zZWdtZW50KGFlcyh4ID0gLW1heF9tYSwgeSA9IHJlb3JkZXIoYWNjZXB0ZWRfbmFtZSwgLWFnZV9tZWFuKSwgeGVuZCA9IC1taW5fbWEsIHllbmQ9cmVvcmRlcihhY2NlcHRlZF9uYW1lLCAtYWdlX21lYW4pLCBjb2xvcj1hY2NlcHRlZF9uYW1lX2NvdW50KSwgYXJyb3c9YXJyb3coZW5kcyA9ICJib3RoIiwgYW5nbGU9OTAsIGxlbmd0aCA9IHVuaXQoMSwgIm1tIikpLCBhbHBoYT0wLjUpICsKICBnZW9tX3BvaW50KGFlcyh4PS1hZ2VfcnVuaWYpLCBjb2w9InJlZCIsIGNleD0xLCBhbHBoYT0wLjUpICsKICBzY2FsZV94X2NvbnRpbnVvdXMobmFtZSA9ICJUaW1lIChNeSkiKSArCiAgc2NhbGVfeV9kaXNjcmV0ZShuYW1lID0gIkFnZSB1bmNlcnRhaW50aWVzIikgKwogIGxhYnMoY29sb3VyPSJBY2NlcHRlZCBuYW1lcyBjb3VudCIpICsKICB0aGVtZShwYW5lbC5ncmlkLm1ham9yLnkgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50ZXh0Lnk9ZWxlbWVudF90ZXh0KHNpemU9MikpICsKICBzY2FsZV9jb2xvcl9ncmFkaWVudG4oY29sb3VycyA9IGMoImRhcmtibHVlIiwgImZvcmVzdGdyZWVuIiwgImJsYWNrIiksIHRyYW5zPSJsb2ciLCBicmVha3M9bXlfYnJlYWtzLCBsYWJlbHM9bXlfYnJlYWtzKSArIAogIGdndGl0bGUoIkRpc3RyaWJ1dGlvbnMgb2YgZm9zc2lsIGFnZSB1bmNlcnRhaW50aWVzIChzcGVjaWVzKSIpICsKICBmYWNldF9ncmlkKGFjY2VwdGVkX3JhbmsgfiAuLCBzY2FsZXMgPSAiZnJlZSIpCgpnZ3Bsb3QoQ2V0YWNlYV9vY2NbQ2V0YWNlYV9vY2MkYWNjZXB0ZWRfcmFuayA9PSJnZW51cyIgJiBDZXRhY2VhX29jYyRhZ2VfdW5jZXJ0YWludHk8MTAsXSwgYWVzKHg9LW1heF9tYSwgeT1hY2NlcHRlZF9uYW1lKSkgKwogIGdlb21fc2VnbWVudChhZXMoeCA9IC1tYXhfbWEsIHkgPSByZW9yZGVyKGFjY2VwdGVkX25hbWUsIC1hZ2VfbWVhbiksIHhlbmQgPSAtbWluX21hLCB5ZW5kPXJlb3JkZXIoYWNjZXB0ZWRfbmFtZSwgLWFnZV9tZWFuKSwgY29sb3I9YWNjZXB0ZWRfbmFtZV9jb3VudCksIGFycm93PWFycm93KGVuZHMgPSAiYm90aCIsIGFuZ2xlPTkwLCBsZW5ndGggPSB1bml0KDEsICJtbSIpKSwgYWxwaGE9MC41KSArCiAgZ2VvbV9wb2ludChhZXMoeD0tYWdlX3J1bmlmKSwgY29sPSJyZWQiLCBjZXg9MSwgYWxwaGE9MC41KSArCiAgc2NhbGVfeF9jb250aW51b3VzKG5hbWUgPSAiVGltZSAoTXkpIikgKwogIHNjYWxlX3lfZGlzY3JldGUobmFtZSA9ICJHZW51cyIpICsKICBsYWJzKGNvbG91cj0iQWNjZXB0ZWQgbmFtZXMgY291bnQiKSArCiAgdGhlbWUocGFuZWwuZ3JpZC5tYWpvci55ID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIGF4aXMudGV4dC55PWVsZW1lbnRfdGV4dChzaXplPTYpKSArCiAgc2NhbGVfY29sb3JfZ3JhZGllbnRuKGNvbG91cnMgPSBjKCJkYXJrYmx1ZSIsICJmb3Jlc3RncmVlbiIsICJibGFjayIpLCB0cmFucz0ibG9nIiwgYnJlYWtzPW15X2JyZWFrcywgbGFiZWxzPW15X2JyZWFrcykgKyAKICBnZ3RpdGxlKCJEaXN0cmlidXRpb25zIG9mIGZvc3NpbCBhZ2UgdW5jZXJ0YWludGllcyAoZ2VuZXJhKSIpICsKICBmYWNldF9ncmlkKGFjY2VwdGVkX3JhbmsgfiAuLCBzY2FsZXMgPSAiZnJlZSIpCgojIGdncGxvdChDZXRhY2VhX29jY1tDZXRhY2VhX29jYyRhY2NlcHRlZF9yYW5rID09ImZhbWlseSIgJiBDZXRhY2VhX29jYyRhZ2VfdW5jZXJ0YWludHk8MTAsXSwgYWVzKHg9LW1heF9tYSwgeT1hY2NlcHRlZF9uYW1lKSkgKwojICAgZ2VvbV9zZWdtZW50KGFlcyh4ID0gLW1heF9tYSwgeSA9IHJlb3JkZXIoYWNjZXB0ZWRfbmFtZSwgLWFnZV9tZWFuKSwgeGVuZCA9IC1taW5fbWEsIHllbmQ9cmVvcmRlcihhY2NlcHRlZF9uYW1lLCAtYWdlX21lYW4pLCBjb2xvcj1hY2NlcHRlZF9uYW1lX2NvdW50KSwgYXJyb3c9YXJyb3coZW5kcyA9ICJib3RoIiwgYW5nbGU9OTAsIGxlbmd0aCA9IHVuaXQoMSwgIm1tIikpLCBhbHBoYT0wLjUpICsKIyAgIGdlb21fcG9pbnQoYWVzKHg9LWFnZV9ydW5pZiksIGNvbD0icmVkIiwgY2V4PTEsIGFscGhhPTAuNSkgKwojICAgc2NhbGVfeF9jb250aW51b3VzKG5hbWUgPSAiVGltZSAoTXkpIikgKwojICAgc2NhbGVfeV9kaXNjcmV0ZShuYW1lID0gIkdlbnVzIikgKwojICAgbGFicyhjb2xvdXI9IkFjY2VwdGVkIG5hbWVzIGNvdW50IikgKwojICAgdGhlbWUocGFuZWwuZ3JpZC5tYWpvci55ID0gZWxlbWVudF9ibGFuaygpKSArCiMgICBzY2FsZV9jb2xvcl9ncmFkaWVudG4oY29sb3VycyA9IGMoImRhcmtibHVlIiwgImZvcmVzdGdyZWVuIiwgImJsYWNrIiksIHRyYW5zPSJsb2ciLCBicmVha3M9bXlfYnJlYWtzLCBsYWJlbHM9bXlfYnJlYWtzKSArIAojICAgZ2d0aXRsZSgiRGlzdHJpYnV0aW9ucyBvZiBmb3NzaWwgYWdlIHVuY2VydGFpbnRpZXMgKGZhbWlsaWVzKSIpICsKIyAgIGZhY2V0X2dyaWQoYWNjZXB0ZWRfcmFuayB+IC4sIHNjYWxlcyA9ICJmcmVlIikKYGBgCgokXHRvJCBTb21lIHRheGEgaGF2ZSBzZXZlcmFsIG9jY3VycmVuY2VzIHdpdGggZGlzdGluY3QgYWdlIHVuY2VydGFpbnR5IGludGVydmFscywgKipsZXQncyBjb21iaW5lIHRoZW0gaW50byBhIHVuaXF1ZSBzdHJhdGlncmFwaGljIHJhbmdlKiouCgojIyMgU3RyYXRpZ3JhcGhpYyByYW5nZXMgPSB1bmlxdWUgdGltZSBpbnRlcnZhbCBjb21iaW5pbmcgYWdlIHVuY2VydGFpbnRpZXMgb2Ygb2NjdXJyZW5jZXMgb2YgdGhlIHNhbWUgdGF4b24gKGV4Y2x1ZGluZyB0aGUgbW9zdCB1bmNlcnRhaW4gb25lcykKCmBgYHtyLCBmaWcuYXNwPTAuNSwgZmlnLndpZHRoPTEwLCB3YXJuaW5nPUZBTFNFfQojIEdldCB0aGUgbWluaW11biBvZiB0aGUgbWluaW1hbCBhZ2VzIGZvciBlYWNoIGFjY2VwdGVkIG5hbWUKQ2V0YWNlYV9vY2MkbWluX21pbl9tYSA8LSBhcHBseShDZXRhY2VhX29jYywgMSwgZnVuY3Rpb24oWCl7bWluKENldGFjZWFfb2NjW0NldGFjZWFfb2NjJGFjY2VwdGVkX25hbWU9PVhbImFjY2VwdGVkX25hbWUiXSAmIENldGFjZWFfb2NjJGFnZV91bmNlcnRhaW50eTwxMCxdJG1pbl9tYSl9KQojIEdldCB0aGUgbWF4aW11bSBvZiB0aGUgbWF4aW1hbCBhZ2VzIGZvciBlYWNoIGFjY2VwdGVkIG5hbWUKQ2V0YWNlYV9vY2MkbWF4X21heF9tYSA8LSBhcHBseShDZXRhY2VhX29jYywgMSwgZnVuY3Rpb24oWCl7bWF4KENldGFjZWFfb2NjW0NldGFjZWFfb2NjJGFjY2VwdGVkX25hbWU9PVhbImFjY2VwdGVkX25hbWUiXSAmIENldGFjZWFfb2NjJGFnZV91bmNlcnRhaW50eTwxMCxdJG1heF9tYSl9KQojIEdldCB0aGUgc3RyYXRpZ3JhcGhpYyByYW5nZQpDZXRhY2VhX29jYyRzdHJhdGlncmFwaGljX3JhbmdlIDwtIG1hcHBseShmdW5jdGlvbihtaW5fbWluX2FnZSwgbWF4X21heF9hZ2Upe3Bhc3RlKCJbIiwtbWF4X21heF9hZ2UsIiwgIiwtbWluX21pbl9hZ2UsIl0iLCBzZXAgPSAiIil9LCBDZXRhY2VhX29jYyRtaW5fbWluX21hLCBDZXRhY2VhX29jYyRtYXhfbWF4X21hKQojIEdldCB0aGUgc3RyYXRpZ3JhcGhpYyByYW5nZSBtaWRwb2ludApDZXRhY2VhX29jYyRzdHJhdGlncmFwaGljX3JhbmdlX21pZHBvaW50IDwtIChDZXRhY2VhX29jYyRtaW5fbWluX21hICsgQ2V0YWNlYV9vY2MkbWF4X21heF9tYSkvMgojIEdldCB0aGUgZHVyYXRpb24gb2YgdGhlIGNvbWJpbmVkIHRpbWUgaW50ZXJ2YWxzCkNldGFjZWFfb2NjJHN0cmF0aWdyYXBoaWNfcmFuZ2VfZHVyYXRpb24gPC0gQ2V0YWNlYV9vY2MkbWF4X21heF9tYS1DZXRhY2VhX29jYyRtaW5fbWluX21hCgojIGdncGxvdChDZXRhY2VhX29jY1shKENldGFjZWFfb2NjJGFjY2VwdGVkX3JhbmsgJWluJSBjKCJzcGVjaWVzIiwgImdlbnVzIiwgImZhbWlseSIpKSAmIENldGFjZWFfb2NjJGFnZV91bmNlcnRhaW50eTwxMCxdLCBhZXMoeD0tbWF4X21hLCB5PWFjY2VwdGVkX25hbWUpKSArCiMgICBnZW9tX3NlZ21lbnQoYWVzKHggPSAtbWF4X21heF9tYSwgeSA9IHJlb3JkZXIoYWNjZXB0ZWRfbmFtZSwgLXN0cmF0aWdyYXBoaWNfcmFuZ2VfbWlkcG9pbnQpLCB4ZW5kID0gLW1pbl9taW5fbWEsIHllbmQ9cmVvcmRlcihhY2NlcHRlZF9uYW1lLCAtc3RyYXRpZ3JhcGhpY19yYW5nZV9taWRwb2ludCksIGNvbG9yPWFjY2VwdGVkX25hbWVfY291bnQpLCBhcnJvdz1hcnJvdyhlbmRzID0gImJvdGgiLCBhbmdsZT05MCwgbGVuZ3RoID0gdW5pdCgxLCAibW0iKSksIGFscGhhPTAuNSkgKwojICAgZ2VvbV9wb2ludChhZXMoeD0tYWdlX3J1bmlmKSwgY29sPSJyZWQiLCBjZXg9MSwgYWxwaGE9MC41KSArCiMgICBzY2FsZV94X2NvbnRpbnVvdXMobmFtZSA9ICJUaW1lIChNeSkiKSArCiMgICBzY2FsZV95X2Rpc2NyZXRlKG5hbWUgPSAiQWNjZXB0ZWQgcmFua3MiKSArCiMgICBsYWJzKGNvbG91cj0iQWNjZXB0ZWQgbmFtZXMgY291bnQiKSArCiMgICB0aGVtZShwYW5lbC5ncmlkLm1ham9yLnkgPSBlbGVtZW50X2JsYW5rKCkpICsKIyAgIHNjYWxlX2NvbG9yX2dyYWRpZW50bihjb2xvdXJzID0gYygiZGFya2JsdWUiLCAiZm9yZXN0Z3JlZW4iLCAiYmxhY2siKSwgdHJhbnM9ImxvZyIsIGJyZWFrcz1teV9icmVha3MsIGxhYmVscz1teV9icmVha3MpICsgCiMgICBnZ3RpdGxlKCJEaXN0cmlidXRpb25zIG9mIGZvc3NpbCBjb21iaW5lZCBhZ2UgdW5jZXJ0YWludGllcywgYnkgYWNjZXB0ZWQgcmFuayIpICsKIyAgIGZhY2V0X2dyaWQoYWNjZXB0ZWRfcmFuayB+IC4sIHNjYWxlcyA9ICJmcmVlIikKCmdncGxvdChDZXRhY2VhX29jY1tDZXRhY2VhX29jYyRhY2NlcHRlZF9yYW5rID09InNwZWNpZXMiICYgQ2V0YWNlYV9vY2MkYWdlX3VuY2VydGFpbnR5PDEwLF0sIGFlcyh4PS1tYXhfbWEsIHk9YWNjZXB0ZWRfbmFtZSkpICsKICBnZW9tX3NlZ21lbnQoYWVzKHggPSAtbWF4X21heF9tYSwgeSA9IHJlb3JkZXIoYWNjZXB0ZWRfbmFtZSwgLXN0cmF0aWdyYXBoaWNfcmFuZ2VfbWlkcG9pbnQpLCB4ZW5kID0gLW1pbl9taW5fbWEsIHllbmQ9cmVvcmRlcihhY2NlcHRlZF9uYW1lLCAtc3RyYXRpZ3JhcGhpY19yYW5nZV9taWRwb2ludCksIGNvbG9yPWFjY2VwdGVkX25hbWVfY291bnQpLCBhcnJvdz1hcnJvdyhlbmRzID0gImJvdGgiLCBhbmdsZT05MCwgbGVuZ3RoID0gdW5pdCgxLCAibW0iKSksIGFscGhhPTAuNSkgKwogIGdlb21fcG9pbnQoYWVzKHg9LWFnZV9ydW5pZiksIGNvbD0icmVkIiwgY2V4PTEsIGFscGhhPTAuNSkgKwogIHNjYWxlX3hfY29udGludW91cyhuYW1lID0gIlRpbWUgKE15KSIpICsKICBzY2FsZV95X2Rpc2NyZXRlKG5hbWUgPSAiQWdlIHVuY2VydGFpbnRpZXMiKSArCiAgbGFicyhjb2xvdXI9IkFjY2VwdGVkIG5hbWVzIGNvdW50IikgKwogIHRoZW1lKHBhbmVsLmdyaWQubWFqb3IueSA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLnRleHQueT1lbGVtZW50X3RleHQoc2l6ZT0yKSkgKwogIHNjYWxlX2NvbG9yX2dyYWRpZW50bihjb2xvdXJzID0gYygiZGFya2JsdWUiLCAiZm9yZXN0Z3JlZW4iLCAiYmxhY2siKSwgdHJhbnM9ImxvZyIsIGJyZWFrcz1teV9icmVha3MsIGxhYmVscz1teV9icmVha3MpICsgCiAgZ2d0aXRsZSgiRGlzdHJpYnV0aW9ucyBvZiBmb3NzaWwgY29tYmluZWQgYWdlIHVuY2VydGFpbnRpZXMgKHNwZWNpZXMpIikgKwogIGZhY2V0X2dyaWQoYWNjZXB0ZWRfcmFuayB+IC4sIHNjYWxlcyA9ICJmcmVlIikKCmdncGxvdChDZXRhY2VhX29jY1tDZXRhY2VhX29jYyRhY2NlcHRlZF9yYW5rID09ImdlbnVzIiAmIENldGFjZWFfb2NjJGFnZV91bmNlcnRhaW50eTwxMCxdLCBhZXMoeD0tbWF4X21hLCB5PWFjY2VwdGVkX25hbWUpKSArCiAgZ2VvbV9zZWdtZW50KGFlcyh4ID0gLW1heF9tYXhfbWEsIHkgPSByZW9yZGVyKGFjY2VwdGVkX25hbWUsIC1zdHJhdGlncmFwaGljX3JhbmdlX21pZHBvaW50KSwgeGVuZCA9IC1taW5fbWluX21hLCB5ZW5kPXJlb3JkZXIoYWNjZXB0ZWRfbmFtZSwgLXN0cmF0aWdyYXBoaWNfcmFuZ2VfbWlkcG9pbnQpLCBjb2xvcj1hY2NlcHRlZF9uYW1lX2NvdW50KSwgYXJyb3c9YXJyb3coZW5kcyA9ICJib3RoIiwgYW5nbGU9OTAsIGxlbmd0aCA9IHVuaXQoMSwgIm1tIikpLCBhbHBoYT0wLjUpICsKICBnZW9tX3BvaW50KGFlcyh4PS1hZ2VfcnVuaWYpLCBjb2w9InJlZCIsIGNleD0xLCBhbHBoYT0wLjUpICsKICBzY2FsZV94X2NvbnRpbnVvdXMobmFtZSA9ICJUaW1lIChNeSkiKSArCiAgc2NhbGVfeV9kaXNjcmV0ZShuYW1lID0gIkdlbmVyYSIpICsKICBsYWJzKGNvbG91cj0iQWNjZXB0ZWQgbmFtZXMgY291bnQiKSArCiAgdGhlbWUocGFuZWwuZ3JpZC5tYWpvci55ID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIGF4aXMudGV4dC55PWVsZW1lbnRfdGV4dChzaXplPTYpKSArCiAgc2NhbGVfY29sb3JfZ3JhZGllbnRuKGNvbG91cnMgPSBjKCJkYXJrYmx1ZSIsICJmb3Jlc3RncmVlbiIsICJibGFjayIpLCB0cmFucz0ibG9nIiwgYnJlYWtzPW15X2JyZWFrcywgbGFiZWxzPW15X2JyZWFrcykgKyAKICBnZ3RpdGxlKCJEaXN0cmlidXRpb25zIG9mIGZvc3NpbCBjb21iaW5lZCBhZ2UgdW5jZXJ0YWludGllcyAoZ2VuZXJhKSIpICsKICBmYWNldF9ncmlkKGFjY2VwdGVkX3JhbmsgfiAuLCBzY2FsZXMgPSAiZnJlZSIpCgojIGdncGxvdChDZXRhY2VhX29jY1tDZXRhY2VhX29jYyRhY2NlcHRlZF9yYW5rID09ImZhbWlseSIgJiBDZXRhY2VhX29jYyRhZ2VfdW5jZXJ0YWludHk8MTAsXSwgYWVzKHg9LW1heF9tYSwgeT1hY2NlcHRlZF9uYW1lKSkgKwojICAgZ2VvbV9zZWdtZW50KGFlcyh4ID0gLW1heF9tYXhfbWEsIHkgPSByZW9yZGVyKGFjY2VwdGVkX25hbWUsIC1zdHJhdGlncmFwaGljX3JhbmdlX21pZHBvaW50KSwgeGVuZCA9IC1taW5fbWluX21hLCB5ZW5kPXJlb3JkZXIoYWNjZXB0ZWRfbmFtZSwgLXN0cmF0aWdyYXBoaWNfcmFuZ2VfbWlkcG9pbnQpLCBjb2xvcj1hY2NlcHRlZF9uYW1lX2NvdW50KSwgYXJyb3c9YXJyb3coZW5kcyA9ICJib3RoIiwgYW5nbGU9OTAsIGxlbmd0aCA9IHVuaXQoMSwgIm1tIikpLCBhbHBoYT0wLjUpICsKIyAgIGdlb21fcG9pbnQoYWVzKHg9LWFnZV9ydW5pZiksIGNvbD0icmVkIiwgY2V4PTEsIGFscGhhPTAuNSkgKwojICAgc2NhbGVfeF9jb250aW51b3VzKG5hbWUgPSAiVGltZSAoTXkpIikgKwojICAgc2NhbGVfeV9kaXNjcmV0ZShuYW1lID0gIkZhbWlsaWVzIikgKwojICAgbGFicyhjb2xvdXI9IkFjY2VwdGVkIG5hbWVzIGNvdW50IikgKwojICAgdGhlbWUocGFuZWwuZ3JpZC5tYWpvci55ID0gZWxlbWVudF9ibGFuaygpKSArCiMgICBzY2FsZV9jb2xvcl9ncmFkaWVudG4oY29sb3VycyA9IGMoImRhcmtibHVlIiwgImZvcmVzdGdyZWVuIiwgImJsYWNrIiksIHRyYW5zPSJsb2ciLCBicmVha3M9bXlfYnJlYWtzLCBsYWJlbHM9bXlfYnJlYWtzKSArIAojICAgZ2d0aXRsZSgiRGlzdHJpYnV0aW9ucyBvZiBmb3NzaWwgY29tYmluZWQgYWdlIHVuY2VydGFpbnRpZXMgKGZhbWlsaWVzKSIpICsKIyAgIGZhY2V0X2dyaWQoYWNjZXB0ZWRfcmFuayB+IC4sIHNjYWxlcyA9ICJmcmVlIikKYGBgCgojIyMgRGVuc2l0eSBkaXN0cmlidXRpb25zCgpQbG90IHRoZSBkZW5zaXR5IG9mIG9jY3VycmVuY2VzICg9IG51bWJlciBvZiBvY2N1cnJlbmNlcyBieSB1bml0IG9mIHRpbWUsIGluIHRoZSBzdHJhdGlncmFwaGljIGludGVydmFsIG9mIGEgdGF4b24pIGZvciBlYWNoIHRheG9ub21pYyByYW5rLgoKYGBge3IsIGZpZy5hc3A9MC41LCBmaWcud2lkdGg9MTF9CiMgR2V0IHRoZSBkZW5zaXR5IG9mIG9jY3VycmVuY2VzIGluIHRoZSBpbnRlcnZhbHMKQ2V0YWNlYV9vY2Mkb2NjdXJyZW5jZV9kZW5zaXR5IDwtIENldGFjZWFfb2NjJGFjY2VwdGVkX25hbWVfY291bnQvQ2V0YWNlYV9vY2MkYWdlX3VuY2VydGFpbnR5CgpnZ3Bsb3QoQ2V0YWNlYV9vY2NbIShDZXRhY2VhX29jYyRhY2NlcHRlZF9yYW5rICVpbiUgYygic3Vic3BlY2llcyIsICJpbmZyYW9yZGVyIikpICYgQ2V0YWNlYV9vY2MkYWdlX3VuY2VydGFpbnR5PDEwLF0sIGFlcyh4PW9jY3VycmVuY2VfZGVuc2l0eSkpICsKICBnZW9tX2hpc3RvZ3JhbShiaW53aWR0aD0wLjEpICsKICBzY2FsZV94X2NvbnRpbnVvdXModHJhbnM9ImxvZzEwIiwgbmFtZT0iRGVuc2l0eSBvZiBvY2N1cnJlbmNlcyAobnVtYmVyL015KSIpICsKICB0aGVtZShwYW5lbC5ncmlkLm1ham9yLnkgPSBlbGVtZW50X2JsYW5rKCkpICsKICBnZ3RpdGxlKCJEaXN0cmlidXRpb25zIG9jY3VycmVuY2UgZGVuc2l0eSwgYnkgYWNjZXB0ZWQgcmFuayIpICsKICBmYWNldF9ncmlkKGFjY2VwdGVkX3JhbmsgfiAuLCBzY2FsZXMgPSAiZnJlZSIpCmBgYAoKJFx0byQgRGVuc2l0eSBsb2dpY2FsbHkgaW5jcmVhc2VzIHdpdGggdGF4YSByYW5rcywgYnV0IHRoZSBkaXN0cmlidXRpb25zIGZvciBzcGVjaWVzIGFuZCBnZW5lcmEgZHJhbWF0aWNhbGx5IHNwcmVhZCBvdmVyIHR3byBvcmRlcnMgb2YgbWFnbml0dWRlLgoKIyMjIENvcnJlbGF0aW9uIGJldHdlZW4gb2NjdXJyZW5jZSBkZW5zaXR5IGFuZCBhZ2UKCklmIHdlIHdhbnQgdG8gY29ycmVjdCBzcGVjaWVzIGFidW5kYW5jZSBkaWZmZXJlbmNlcyBiYXNlZCBvbiB0aGUgZGVuc2l0eSBvZiBvY2N1cnJlbmNlcyBpbiB0aGUgYWdlIGludGVydmFsLCB0aG9zZSBmYWN0b3JzIHNob3VsZCBub3QgZGVwZW5kIG9uIHRpbWUgaW4gb3JkZXIgdG8gYXZvaWQgcGVuYWxpemluZyBwZXJpb2RzIHdpdGggaGlnaGVyIGRlbnNpdGllcy4KCkxldCdzIGNvbXBhcmUgdGhlIG9jY3VycmVuY2UgZGVuc2l0aWVzIGNvbXB1dGVkIHdpdGggdGhlIGluaXRpYWwgdGltZSByYW5nZXMgYW5kIHRoZSAqY29tYmluZWQgZGVuc2l0aWVzKiBjb21wdXRlZCB3aXRoIHRoZSBjb21iaW5lZCBzdHJhdGlncmFwaGljIHJhbmdlcy4KCmBgYHtyfQpjb25kaXRpb25zIDwtIENldGFjZWFfb2NjJGFjY2VwdGVkX3JhbmsgPT0ic3BlY2llcyIgJiBDZXRhY2VhX29jYyRhZ2VfdW5jZXJ0YWludHk8MTAKCiMgR2V0IHRoZSBzdHJhdGlncmFwaGljIGFnZSB1bmNlcnRhaW50eSBpbnRlcnZhbApDZXRhY2VhX29jYyRhZ2VfdW5jZXJ0YWludHlfaW50ZXJ2YWwgPC0gbWFwcGx5KGZ1bmN0aW9uKG1pbl9hZ2UsIG1heF9hZ2Upe3Bhc3RlKCJbIiwtbWF4X2FnZSwiLCAiLC1taW5fYWdlLCJdIiwgc2VwID0gIiIpfSwgQ2V0YWNlYV9vY2MkbWluX21hLCBDZXRhY2VhX29jYyRtYXhfbWEpCgojIEZ1bmN0aW9uIHRvIHBsb3QgbGluZWFyIHJlZ3Jlc3Npb24gY29lZmZpY2llbnRzCmxtX2VxbiA8LSBmdW5jdGlvbihkZil7CiAgICBtIDwtIGxtKHkgfiB4LCBkZik7CiAgICBlcSA8LSBzdWJzdGl0dXRlKGl0YWxpYyh5KSA9PSBhICsgYiAlLiUgaXRhbGljKHgpKiIsIn5+aXRhbGljKHIpXjJ+Ij0ifnIyLCAKICAgICAgICAgbGlzdChhID0gZm9ybWF0KHVubmFtZShjb2VmKG0pWzFdKSwgZGlnaXRzID0gMiksCiAgICAgICAgICAgICAgYiA9IGZvcm1hdCh1bm5hbWUoY29lZihtKVsyXSksIGRpZ2l0cyA9IDIpLAogICAgICAgICAgICAgcjIgPSBmb3JtYXQoc3VtbWFyeShtKSRyLnNxdWFyZWQsIGRpZ2l0cyA9IDMpKSkKICAgIGFzLmNoYXJhY3Rlcihhcy5leHByZXNzaW9uKGVxKSk7Cn0KCiMgS2VlcCBvbmx5IG9uZSBwb2ludCBieSBpZGVudGljYWwgdGltZSBpbnRlcnZhbAphZ2VfdW5jZXJ0YWludHlfaW50ZXJ2YWxfdGFibGUgPC0gdGFibGUoQ2V0YWNlYV9vY2NbY29uZGl0aW9ucyxdJGFnZV91bmNlcnRhaW50eV9pbnRlcnZhbCkKCmludGVydmFsX21lYW5fYWdlIDwtIHNhcHBseShuYW1lcyhhZ2VfdW5jZXJ0YWludHlfaW50ZXJ2YWxfdGFibGUpLCBmdW5jdGlvbih4KXtDZXRhY2VhX29jY1tjb25kaXRpb25zICYgQ2V0YWNlYV9vY2MkYWdlX3VuY2VydGFpbnR5X2ludGVydmFsPT14LF0kYWdlX21lYW5bMV19KQoKaW50ZXJ2YWxfZGVuc2l0eSA8LSBzYXBwbHkobmFtZXMoYWdlX3VuY2VydGFpbnR5X2ludGVydmFsX3RhYmxlKSwgZnVuY3Rpb24oeCl7Q2V0YWNlYV9vY2NbY29uZGl0aW9ucyAmIENldGFjZWFfb2NjJGFnZV91bmNlcnRhaW50eV9pbnRlcnZhbD09eCxdJG9jY3VycmVuY2VfZGVuc2l0eVsxXX0pCgpkZl9kZW5zaXR5IDwtIGRhdGEuZnJhbWUoeD1pbnRlcnZhbF9tZWFuX2FnZSwKICAgICAgICAgICAgICAgICAgICAgICAgIHk9aW50ZXJ2YWxfZGVuc2l0eSkKCmdncGxvdChkZl9kZW5zaXR5LCBhZXMoeD14LCB5PXkpKSArIAogIGdlb21fcG9pbnQoYWxwaGE9MC41KSArCiAgZ2VvbV9zbW9vdGgoZm9ybXVsYSA9IHl+eCwgbWV0aG9kPWxtKSArIAogIHNjYWxlX3hfY29udGludW91cyhuYW1lID0gIlRpbWUgKE15KSIpICsKICBzY2FsZV95X2NvbnRpbnVvdXMobmFtZSA9ICJPY2N1cnJlbmNlIGRlbnNpdHkiKSArCiAgZ2d0aXRsZSgiQ29ycmVsYXRpb24gYmV0d2VlbiBkZW5zaXR5IGFuZCBhZ2UiKSArCiAgZ2VvbV90ZXh0KHggPSAzNSwgeSA9IDI1LCBsYWJlbCA9IGxtX2VxbihkZl9kZW5zaXR5KSwgcGFyc2UgPSBUUlVFKQoKIyBLZWVwIG9ubHkgb25lIHBvaW50IGJ5IGlkZW50aWNhbCBzdHJhdGlncmFwaGljIHJhbmdlCnN0cmF0aWdyYXBoaWNfcmFuZ2VfdGFibGUgPC0gdGFibGUoQ2V0YWNlYV9vY2NbY29uZGl0aW9ucyxdJHN0cmF0aWdyYXBoaWNfcmFuZ2UpCgpzdHJhdGlncmFwaGljX3JhbmdlX21lYW5fYWdlIDwtIHNhcHBseShuYW1lcyhzdHJhdGlncmFwaGljX3JhbmdlX3RhYmxlKSwgZnVuY3Rpb24oeCl7Q2V0YWNlYV9vY2NbY29uZGl0aW9ucyAmIENldGFjZWFfb2NjJHN0cmF0aWdyYXBoaWNfcmFuZ2U9PXgsXSRzdHJhdGlncmFwaGljX3JhbmdlX21pZHBvaW50WzFdfSkKCkNldGFjZWFfb2NjJG9jY3VycmVuY2VfY29tYmluZWRfZGVuc2l0eSA8LSBDZXRhY2VhX29jYyRhY2NlcHRlZF9uYW1lX2NvdW50L0NldGFjZWFfb2NjJHN0cmF0aWdyYXBoaWNfcmFuZ2VfZHVyYXRpb24KCnN0cmF0aWdyYXBoaWNfcmFuZ2VfZGVuc2l0eSA8LSBzYXBwbHkobmFtZXMoc3RyYXRpZ3JhcGhpY19yYW5nZV90YWJsZSksIGZ1bmN0aW9uKHgpe0NldGFjZWFfb2NjW2NvbmRpdGlvbnMgJiBDZXRhY2VhX29jYyRzdHJhdGlncmFwaGljX3JhbmdlPT14LF0kb2NjdXJyZW5jZV9jb21iaW5lZF9kZW5zaXR5WzFdfSkKCnN0cmF0aWdyYXBoaWNfcmFuZ2VfZGZfZGVuc2l0eSA8LSBkYXRhLmZyYW1lKHg9c3RyYXRpZ3JhcGhpY19yYW5nZV9tZWFuX2FnZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeT1zdHJhdGlncmFwaGljX3JhbmdlX2RlbnNpdHkpCgpnZ3Bsb3Qoc3RyYXRpZ3JhcGhpY19yYW5nZV9kZl9kZW5zaXR5LCBhZXMoeD14LCB5PXkpKSArIAogIGdlb21fcG9pbnQoYWxwaGE9MC41KSArCiAgZ2VvbV9zbW9vdGgoZm9ybXVsYSA9IHl+eCwgbWV0aG9kPWxtKSArIAogIHNjYWxlX3hfY29udGludW91cyhuYW1lID0gIlRpbWUgKE15KSIpICsKICBzY2FsZV95X2NvbnRpbnVvdXMobmFtZSA9ICJDb21iaW5lZCBvY2N1cnJlbmNlIGRlbnNpdHkiKSArCiAgZ2d0aXRsZSgiQ29ycmVsYXRpb24gYmV0d2VlbiBjb21iaW5lZCBkZW5zaXR5IGFuZCBhZ2UiKSArCiAgZ2VvbV90ZXh0KHggPSAxNSwgeSA9IDYsIGxhYmVsID0gbG1fZXFuKHN0cmF0aWdyYXBoaWNfcmFuZ2VfZGZfZGVuc2l0eSksIHBhcnNlID0gVFJVRSkKYGBgCgokXHRvJCBUaGUgZGVuc2l0eSBiYXNlZCBvbiBjb21iaW5lZCByYW5nZXMgc2VlbXMgbGVzcyB0aW1lLWRlcGVuZGVudCB0aGFuIHRoZSBkZW5zaXR5IGJhc2VkIG9uIGluaXRpYWwgdGltZSByYW5nZXMuIFdlIHdpbGwgdGhlcmVmb3JlIHVzZSB0aGUgY29tYmluZWQgZGVuc2l0eSBmb3Igb3VyIGNvcnJlY3Rpb25zLgoKIyMgQklBUyBDT1JSRUNUSU9OIE7CsDM6IFN1YnNhbXBsZSBvY2N1cnJlbmNlcyBieSBob21vZ2VuaXppbmcgdGhlIGNvbWJpbmVkIG9jY3VycmVuY2UgZGVuc2l0eQoKKipTdWJzYW1wbGluZyBieSBob21vZ2VuaXphdGlvbioqID0gcmVkdWNpbmcgdGhlIGRpc2NyZXBhbmN5IGJldHdlZW4gaGlnaCBhbmQgbG93IG9jY3VycmVuY2UgZGVuc2l0aWVzIGFtb25nIHRheGEgYnkgc3Vic2FtcGxpbmcgcHJlZmVyZW50aWFsbHkgdGhlIGRlbnNlc3Qgb25lcy4KCiMjIyBDb21wYXJlIGRlbnNpdGllcyBieSBhY2NlcHRlZCBuYW1lIGNvdW50IChzcGVjaWVzIG9ubHkpCgpMZXQncyBmb2N1cyBub3cgb24gdGhlIG9jY3VycmVuY2VzIGFjY2VwdGVkIGF0IHRoZSBzcGVjaWVzIGxldmVsIGJlY2F1c2UgdGhleSBhcmUgdGhlIG9uZSBmb3Igd2hpY2ggd2UgY2FuIGNvcnJlY3QgdGhlIGFidW5kYW5jZSBiaWFzIGJ5IHN1YnNhbXBsaW5nIHRoZSBtb3N0IGNvbmNlbnRyYXRlZCBjb21iaW5lZCBpbnRlcnZhbHMuCgpgYGB7ciwgZmlnLmFzcD0wLjUsIGZpZy53aWR0aD0xMn0KY29uZGl0aW9ucyA8LSBDZXRhY2VhX29jYyRhY2NlcHRlZF9yYW5rID09InNwZWNpZXMiICYgQ2V0YWNlYV9vY2MkYWdlX3VuY2VydGFpbnR5PDEwCgojIGdncGxvdChDZXRhY2VhX29jY1tjb25kaXRpb25zLF0sIGFlcyh4PW9jY3VycmVuY2VfZGVuc2l0eSwgZmlsbD1mYWN0b3IoYWNjZXB0ZWRfbmFtZV9jb3VudCkpKSArCiMgICBnZW9tX2hpc3RvZ3JhbShiaW53aWR0aD0wLjEpICsKIyAgIHNjYWxlX3hfY29udGludW91cyh0cmFucz0ibG9nMTAiLCBuYW1lPSJEZW5zaXR5IG9mIG9jY3VycmVuY2VzIChudW1iZXIvTXkpIikgKwojICAgc2NhbGVfZmlsbF9kaXNjcmV0ZShuYW1lPSJBY2NlcHRlZCBuYW1lIGNvdW50IikgKwojICAgdGhlbWUocGFuZWwuZ3JpZC5tYWpvci55ID0gZWxlbWVudF9ibGFuaygpKSArCiMgICBnZ3RpdGxlKCJEaXN0cmlidXRpb25zIG9mIG9jY3VycmVuY2UgZGVuc2l0eSBhbW9uZyBzcGVjaWVzIikgKwojICAgZmFjZXRfZ3JpZChhY2NlcHRlZF9uYW1lX2NvdW50IH4gLiwgc2NhbGVzID0gImZyZWUiKQoKZ2dwbG90KENldGFjZWFfb2NjW2NvbmRpdGlvbnMsXSwgYWVzKHg9b2NjdXJyZW5jZV9jb21iaW5lZF9kZW5zaXR5LCBmaWxsPWZhY3RvcihhY2NlcHRlZF9uYW1lX2NvdW50KSkpICsKICBnZW9tX2hpc3RvZ3JhbShiaW53aWR0aD0wLjA1KSArCiAgc2NhbGVfeF9jb250aW51b3VzKHRyYW5zPSJsb2cxMCIsIG5hbWU9IkNvbWJpbmVkIGRlbnNpdHkgb2Ygb2NjdXJyZW5jZXMgKG51bWJlci9NeSkiKSArCiAgc2NhbGVfZmlsbF9kaXNjcmV0ZShuYW1lPSJBY2NlcHRlZCBuYW1lIGNvdW50IikgKwogIHRoZW1lKHBhbmVsLmdyaWQubWFqb3IueSA9IGVsZW1lbnRfYmxhbmsoKSkgKwogIGdndGl0bGUoIkRpc3RyaWJ1dGlvbnMgb2YgY29tYmluZWQgb2NjdXJyZW5jZSBkZW5zaXR5IGFtb25nIHNwZWNpZXMiKSArCiAgZmFjZXRfZ3JpZChhY2NlcHRlZF9uYW1lX2NvdW50IH4gLiwgc2NhbGVzID0gImZyZWUiKQpgYGAKCiRcdG8kIFRoZWlyIGlzIGEgaHVnZSBzcGFuIG9mIGRlbnNpdGllcyBkcml2ZW4gYnkgdGhlIG51bWJlciBvZiBvY2N1cnJlbmNlcyBmb3IgdGhlIHNhbWUgc3BlY2llcyB0aGF0IHdlIGNhbiByZWR1Y2UgYnkgc3Vic2FtcGxpbmcgdGhlIG1vc3QgY29uY2VudHJhdGVkIGludGVydmFscy4KCiMjIyBJbXBhY3Qgb2YgY29ycmVjdGluZyBzdWJzYW1wbGluZyBvbiBkZW5zaXR5IGRpc3RyaWJ1dGlvbnMgKHNwZWNpZXMgb25seSkKCmBgYHtyLCBmaWcuYXNwPTAuNCwgZmlnLndpZHRoPTEyfQpjb25kaXRpb25zIDwtIENldGFjZWFfb2NjJGFjY2VwdGVkX3JhbmsgPT0ic3BlY2llcyIgJiBDZXRhY2VhX29jYyRhZ2VfdW5jZXJ0YWludHk8MTAKCiMgZ2dwbG90KENldGFjZWFfb2NjW2NvbmRpdGlvbnMsXSwgYWVzKHg9b2NjdXJyZW5jZV9jb21iaW5lZF9kZW5zaXR5LCBmaWxsPWZhY3RvcihhY2NlcHRlZF9uYW1lX2NvdW50KSkpICsKIyAgIGdlb21faGlzdG9ncmFtKGJpbndpZHRoPTAuMDUpICsKIyAgIHNjYWxlX3hfY29udGludW91cyh0cmFucz0ibG9nMTAiLCBuYW1lPSJDb21iaW5lZCBkZW5zaXR5IG9mIG9jY3VycmVuY2VzIChudW1iZXIvTXkpIikgKwojICAgc2NhbGVfZmlsbF9kaXNjcmV0ZShuYW1lPSJBY2NlcHRlZCBuYW1lIGNvdW50IikgKwojICAgdGhlbWUocGFuZWwuZ3JpZC5tYWpvci55ID0gZWxlbWVudF9ibGFuaygpKSArCiMgICBnZ3RpdGxlKHBhc3RlKCJEaXN0cmlidXRpb25zIG9mIGNvbWJpbmVkIG9jY3VycmVuY2UgZGVuc2l0eSBhbW9uZyBzcGVjaWVzIChuID0gIiwgZGltKENldGFjZWFfb2NjW2NvbmRpdGlvbnMsXSlbMV0sICIpIiwgc2VwPSIiKSkgKwojICAgZmFjZXRfZ3JpZChhY2NlcHRlZF9uYW1lX2NvdW50IH4gLiwgc2NhbGVzID0gImZyZWUiKQoKIyBBZGQgYXQgbGVhc3Qgb25lIG9jY3VycmVuY2Ugb2YgZWFjaCBzcGVjaWVzCkNldGFjZWFfb2NjX3NhbXBsZWQgPC0gYygpCkNldGFjZWFfb2NjX25vdHNhbXBsZWQgPC0gYygpCmZvciAoaSBpbiBhcy5udW1lcmljKHJvdy5uYW1lcyhDZXRhY2VhX29jY1tjb25kaXRpb25zLF0pKSl7CiAgcm93IDwtIENldGFjZWFfb2NjW2FzLmNoYXJhY3RlcihpKSxdCiAgaWYgKCEocm93JGFjY2VwdGVkX25hbWUgJWluJSBDZXRhY2VhX29jY19zYW1wbGVkJGFjY2VwdGVkX25hbWUpKXsKICAgIENldGFjZWFfb2NjX3NhbXBsZWQgPC0gcmJpbmQoQ2V0YWNlYV9vY2Nfc2FtcGxlZCwgcm93KQogIH1lbHNlewogICAgQ2V0YWNlYV9vY2Nfbm90c2FtcGxlZCA8LSByYmluZChDZXRhY2VhX29jY19ub3RzYW1wbGVkLCByb3cpCiAgfQp9CgojIEFkZCBvY2N1cnJlbmNlcyBpbiB0aGUgcmVtYW5pbmcgb25lcywgYnkgdW5kZXJ3ZWlnaHRpbmcgZGVuc2Ugc3BlY2llcwpDZXRhY2VhX29jY19zYW1wbGVkIDwtIHJiaW5kKENldGFjZWFfb2NjX3NhbXBsZWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNhbXBsZV9uKENldGFjZWFfb2NjX25vdHNhbXBsZWQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplPTgwMC1kaW0oQ2V0YWNlYV9vY2Nfc2FtcGxlZClbMV0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdlaWdodD0xL0NldGFjZWFfb2NjX25vdHNhbXBsZWQkb2NjdXJyZW5jZV9jb21iaW5lZF9kZW5zaXR5KiozKSkKCkNldGFjZWFfb2NjX3NhbXBsZWQkbWluX21pbl9tYSA8LSBhcHBseShDZXRhY2VhX29jY19zYW1wbGVkLCAxLCBmdW5jdGlvbihYKXttaW4oQ2V0YWNlYV9vY2Nfc2FtcGxlZFtDZXRhY2VhX29jY19zYW1wbGVkJGFjY2VwdGVkX25hbWU9PVhbImFjY2VwdGVkX25hbWUiXSxdJG1pbl9tYSl9KQpDZXRhY2VhX29jY19zYW1wbGVkJG1heF9tYXhfbWEgPC0gYXBwbHkoQ2V0YWNlYV9vY2Nfc2FtcGxlZCwgMSwgZnVuY3Rpb24oWCl7bWF4KENldGFjZWFfb2NjX3NhbXBsZWRbQ2V0YWNlYV9vY2Nfc2FtcGxlZCRhY2NlcHRlZF9uYW1lPT1YWyJhY2NlcHRlZF9uYW1lIl0sXSRtYXhfbWEpfSkKQ2V0YWNlYV9vY2Nfc2FtcGxlZCRzdHJhdGlncmFwaGljX3JhbmdlX2R1cmF0aW9uIDwtIENldGFjZWFfb2NjX3NhbXBsZWQkbWF4X21heF9tYS1DZXRhY2VhX29jY19zYW1wbGVkJG1pbl9taW5fbWEKQ2V0YWNlYV9vY2Nfc2FtcGxlZCRhY2NlcHRlZF9uYW1lX2NvdW50IDwtIHNhcHBseShDZXRhY2VhX29jY19zYW1wbGVkJGFjY2VwdGVkX25hbWUsIGZ1bmN0aW9uKHgpe3RhYmxlKENldGFjZWFfb2NjX3NhbXBsZWQkYWNjZXB0ZWRfbmFtZSlbeF19KQpDZXRhY2VhX29jY19zYW1wbGVkJG9jY3VycmVuY2VfY29tYmluZWRfZGVuc2l0eSA8LSBDZXRhY2VhX29jY19zYW1wbGVkJGFjY2VwdGVkX25hbWVfY291bnQvQ2V0YWNlYV9vY2Nfc2FtcGxlZCRzdHJhdGlncmFwaGljX3JhbmdlX2R1cmF0aW9uCgoKZ2dwbG90KENldGFjZWFfb2NjX3NhbXBsZWQsIGFlcyh4PW9jY3VycmVuY2VfY29tYmluZWRfZGVuc2l0eSwgZmlsbD1mYWN0b3IoYWNjZXB0ZWRfbmFtZV9jb3VudCkpKSArCiAgZ2VvbV9oaXN0b2dyYW0oYmlud2lkdGg9MC4wNSkgKwogIHNjYWxlX3hfY29udGludW91cyh0cmFucz0ibG9nMTAiLCBuYW1lPSJDb21iaW5lZCBkZW5zaXR5IG9mIG9jY3VycmVuY2VzIChudW1iZXIvTXkpIiwgbGltaXRzPWMoMC4xLCAxMDAwKSkgKwogIHNjYWxlX2ZpbGxfZGlzY3JldGUobmFtZT0iQWNjZXB0ZWQgbmFtZSBjb3VudCIpICsKICB0aGVtZShwYW5lbC5ncmlkLm1ham9yLnkgPSBlbGVtZW50X2JsYW5rKCkpICsKICBnZ3RpdGxlKHBhc3RlKCJEaXN0cmlidXRpb25zIG9mIGNvbWJpbmVkIG9jY3VycmVuY2UgZGVuc2l0eSBhbW9uZyBzcGVjaWVzLCBhZnRlciBzYW1wbGluZyAobiA9ICIsIGRpbShDZXRhY2VhX29jY19zYW1wbGVkKVsxXSwgIikiLCBzZXA9IiIpKSArCiAgZmFjZXRfZ3JpZChhY2NlcHRlZF9uYW1lX2NvdW50IH4gLiwgc2NhbGVzID0gImZyZWUiKQpgYGAKCiRcdG8kIFN1YnNhbXBsaW5nIGJ5IGhvbW9nZW5pemF0aW9uIHN1Y2Nlc3NmdWxseSByZWR1Y2VzIHRoZSBkZW5zaXR5IHNwYW4gZnJvbSAyIHRvIDEgb3JkZXIgb2YgbWFnbml0dWRlLgoKIyMjIEltcGFjdCBvZiBzdWJzYW1wbGluZyBvbiBvY2N1cnJlbmNlcyByZXBhcnRpdGlvbiAoc3BlY2llcyBvbmx5KQoKU2VlIHdoYXQgb3VyIGRpc3RyaWJ1dGlvbnMgbG9vayBsaWtlIGFmdGVyIHN1YnNhbXBsaW5nOgoKYGBge3IsIGZpZy5hc3A9MC41LCBmaWcud2lkdGg9MTJ9CmJyZWFrcyA8LSBjKDAuMTI1LDAuMjUsMC41LDEsMiw0LDgsMTYpCgojIGdncGxvdChDZXRhY2VhX29jY1tDZXRhY2VhX29jYyRhY2NlcHRlZF9yYW5rID09InNwZWNpZXMiICYgQ2V0YWNlYV9vY2MkYWdlX3VuY2VydGFpbnR5PDEwLF0sIGFlcyh4PS1tYXhfbWEsIHk9YWNjZXB0ZWRfbmFtZSkpICsKIyAgIGdlb21fc2VnbWVudChhZXMoeCA9IC1tYXhfbWF4X21hLCB5ID0gcmVvcmRlcihhY2NlcHRlZF9uYW1lLCAtc3RyYXRpZ3JhcGhpY19yYW5nZV9taWRwb2ludCksIHhlbmQgPSAtbWluX21pbl9tYSwgeWVuZD1yZW9yZGVyKGFjY2VwdGVkX25hbWUsIC1zdHJhdGlncmFwaGljX3JhbmdlX21pZHBvaW50KSwgY29sb3I9b2NjdXJyZW5jZV9jb21iaW5lZF9kZW5zaXR5KSwgYXJyb3c9YXJyb3coZW5kcyA9ICJib3RoIiwgYW5nbGU9OTAsIGxlbmd0aCA9IHVuaXQoMSwgIm1tIikpLCBhbHBoYT0wLjUpICsKIyAgIGdlb21fcG9pbnQoYWVzKHg9LWFnZV9ydW5pZiksIGNvbD0icmVkIiwgY2V4PTAuNSwgYWxwaGE9MC41KSArCiMgICBzY2FsZV94X2NvbnRpbnVvdXMobmFtZSA9ICJUaW1lIChNeSkiKSArCiMgICBzY2FsZV95X2Rpc2NyZXRlKG5hbWUgPSAiU3BlY2llcyIpICsKIyAgIGxhYnMoY29sb3VyPSJPY2N1cnJlbmNlXG5kZW5zaXR5IikgKwojICAgdGhlbWUoYXhpcy50ZXh0Lnk9ZWxlbWVudF9ibGFuaygpLAojICAgICAgICAgYXhpcy50aWNrcy55PWVsZW1lbnRfYmxhbmsoKSwKIyAgICAgICAgIHBhbmVsLmdyaWQubWFqb3IueSA9IGVsZW1lbnRfYmxhbmsoKSkgKwojICAgc2NhbGVfY29sb3JfZ3JhZGllbnRuKGNvbG91cnMgPSBjKCJkYXJrYmx1ZSIsICJmb3Jlc3RncmVlbiIsICJibGFjayIpLCB0cmFucz0ibG9nIiwgYnJlYWtzPWJyZWFrcywgbGFiZWxzPWJyZWFrcykgKyAKIyAgIGdndGl0bGUocGFzdGUoIkRpc3RyaWJ1dGlvbnMgb2Ygc3BlY2llcyBmb3NzaWwgYWdlIHVuY2VydGFpbnRpZXMsIGJlZm9yZSBjb3JyZWN0aW5nIHNhbXBsaW5nIChuID0gIiwgZGltKENldGFjZWFfb2NjW0NldGFjZWFfb2NjJGFjY2VwdGVkX3JhbmsgPT0ic3BlY2llcyIgJiBDZXRhY2VhX29jYyRhZ2VfdW5jZXJ0YWludHk8MTAsXSlbMV0sICIpIiwgc2VwPSIiKSkKCmdncGxvdChDZXRhY2VhX29jY19zYW1wbGVkLCBhZXMoeD0tbWF4X21hLCB5PWFjY2VwdGVkX25hbWUpKSArCiAgZ2VvbV9zZWdtZW50KGFlcyh4ID0gLW1heF9tYXhfbWEsIHkgPSByZW9yZGVyKGFjY2VwdGVkX25hbWUsIC1zdHJhdGlncmFwaGljX3JhbmdlX21pZHBvaW50KSwgeGVuZCA9IC1taW5fbWluX21hLCB5ZW5kPXJlb3JkZXIoYWNjZXB0ZWRfbmFtZSwgLXN0cmF0aWdyYXBoaWNfcmFuZ2VfbWlkcG9pbnQpLCBjb2xvcj1vY2N1cnJlbmNlX2NvbWJpbmVkX2RlbnNpdHkpLCBhcnJvdz1hcnJvdyhlbmRzID0gImJvdGgiLCBhbmdsZT05MCwgbGVuZ3RoID0gdW5pdCgxLCAibW0iKSksIGFscGhhPTAuNSkgKwogIGdlb21fcG9pbnQoYWVzKHg9LWFnZV9ydW5pZiksIGNvbD0icmVkIiwgY2V4PTAuNSwgYWxwaGE9MC41KSArCiAgc2NhbGVfeF9jb250aW51b3VzKG5hbWUgPSAiVGltZSAoTXkpIikgKwogIHNjYWxlX3lfZGlzY3JldGUobmFtZSA9ICJTcGVjaWVzIikgKwogIGxhYnMoY29sb3VyPSJPY2N1cnJlbmNlXG5kZW5zaXR5IikgKwogIHRoZW1lKGF4aXMudGV4dC55PWVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLnRpY2tzLnk9ZWxlbWVudF9ibGFuaygpLAogICAgICAgIHBhbmVsLmdyaWQubWFqb3IueSA9IGVsZW1lbnRfYmxhbmsoKSkgKwogIHNjYWxlX2NvbG9yX2dyYWRpZW50bihjb2xvdXJzID0gYygiZGFya2JsdWUiLCAiZm9yZXN0Z3JlZW4iLCAiYmxhY2siKSwgdHJhbnM9ImxvZyIsIGJyZWFrcz1icmVha3MsIGxhYmVscz1icmVha3MpICsgCiAgZ2d0aXRsZShwYXN0ZSgiRGlzdHJpYnV0aW9ucyBvZiBzcGVjaWVzIGZvc3NpbCBhZ2UgdW5jZXJ0YWludGllcywgYWZ0ZXIgc3Vic2FtcGxpbmcgYnkgaG9tb2dlbml6YXRpb24gKG4gPSAiLCBkaW0oQ2V0YWNlYV9vY2Nfc2FtcGxlZClbMV0sICIpIiwgc2VwPSIiKSkKYGBgCgokXHRvJCBTb21lIGhpZ2hseSBkZW5zZSBjbHVzdGVyIGJlY2FtZSBtdWNoIG1vcmUgc2ltaWxhciB0byB0aGUgb3RoZXJzLgoKYGBge3IgZmlnLndpZHRoPTEwLCBmaWcuYXNwPTAuM30KY29uZGl0aW9ucyA8LSBDZXRhY2VhX29jYyRhY2NlcHRlZF9yYW5rID09InNwZWNpZXMiICYgQ2V0YWNlYV9vY2MkYWdlX3VuY2VydGFpbnR5PDEwCgpnZ3Bsb3QoQ2V0YWNlYV9vY2NbY29uZGl0aW9ucyxdLCBhZXMoeD0tYWdlX3J1bmlmKSkgKwogIGdlb21faGlzdG9ncmFtKGJpbndpZHRoID0gMC41LCBhbHBoYT0wLjUsIGZpbGw9InJlZCIpICsKICBzY2FsZV94X2NvbnRpbnVvdXMobmFtZSA9ICJUaW1lIChNeSkiKSArCiAgc2NhbGVfeV9jb250aW51b3VzKG5hbWUgPSAiTnVtYmVyIG9mIG9jY3VycmVuY2VzIikgKwogIHNjYWxlX2ZpbGxfZGlzY3JldGUobmFtZT0iQWNjZXB0ZWQgcmFuayIpICsKICB0aGVtZShwYW5lbC5ncmlkLm1ham9yLnkgPSBlbGVtZW50X2JsYW5rKCkpICsKICBnZ3RpdGxlKHBhc3RlKCJFdm9sdXRpb24gb2YgdGhlIHNwZWNpZXMgb2NjdXJyZW5jZSBudW1iZXIgdGhyb3VnaCB0aW1lIChuID0gIiwgZGltKENldGFjZWFfb2NjW2NvbmRpdGlvbnMsXSlbMV0sICIpIiwgc2VwPSIiKSkKCmdncGxvdChDZXRhY2VhX29jY19zYW1wbGVkLCBhZXMoeD0tYWdlX3J1bmlmKSkgKwogIGdlb21faGlzdG9ncmFtKGJpbndpZHRoID0gMC41LCBhbHBoYT0wLjUsIGZpbGw9ImJsdWUiKSArCiAgc2NhbGVfeF9jb250aW51b3VzKG5hbWUgPSAiVGltZSAoTXkpIikgKwogIHNjYWxlX3lfY29udGludW91cyhuYW1lID0gIk51bWJlciBvZiBvY2N1cnJlbmNlcyIpICsKICBzY2FsZV9maWxsX2Rpc2NyZXRlKG5hbWU9IkFjY2VwdGVkIHJhbmsiKSArCiAgdGhlbWUocGFuZWwuZ3JpZC5tYWpvci55ID0gZWxlbWVudF9ibGFuaygpKSArCiAgZ2d0aXRsZShwYXN0ZSgiRXZvbHV0aW9uIG9mIHRoZSBzcGVjaWVzIG9jY3VycmVuY2UgbnVtYmVyIHRocm91Z2ggdGltZSwgYWZ0ZXIgc3Vic2FtcGxpbmcgYnkgaG9tb2dlbml6YXRpb24gKG4gPSAiLCBkaW0oQ2V0YWNlYV9vY2Nfc2FtcGxlZClbMV0sICIpIiwgc2VwPSIiKSkKYGBgCgpJZiB3ZSBzdXBlcnBvc2UgdGhlc2UgMiBwbG90czoKCmBgYHtyIGZpZy53aWR0aD0xMCwgZmlnLmFzcD0wLjR9CmNvbmRpdGlvbnMgPC0gQ2V0YWNlYV9vY2MkYWNjZXB0ZWRfcmFuayA9PSJzcGVjaWVzIiAmIENldGFjZWFfb2NjJGFnZV91bmNlcnRhaW50eTwxMAoKcDEgPC0gZ2dwbG90KENldGFjZWFfb2NjW2NvbmRpdGlvbnMsXSwgYWVzKHg9LWFnZV9ydW5pZikpICsKICBnZW9tX2hpc3RvZ3JhbShiaW53aWR0aCA9IDAuNSwgYWxwaGE9MC41LCBmaWxsPSJyZWQiKSArCiAgdGhlbWVfdm9pZCgpCgpwMiA8LSBnZ3Bsb3QoQ2V0YWNlYV9vY2Nfc2FtcGxlZCwgYWVzKHg9LWFnZV9ydW5pZikpICsKICBnZW9tX2hpc3RvZ3JhbShiaW53aWR0aCA9IDAuNSwgYWxwaGE9MC41LCBmaWxsPSJibHVlIikgKwogIHRoZW1lX3ZvaWQoKQoKcDEgKyBhbm5vdGF0aW9uX2N1c3RvbShnZ3Bsb3RHcm9iKHAyKSkKYGBgCgokXHRvJCBXZSBnZXQgdGhlIG5ldyBzcGVjaWVzIG9jY3VycmVuY2UgZGlzdHJpYnV0aW9uIGFmdGVyIHN1YnNhbXBsaW5nLCB0aGF0IGNvdWxkIGJlIHVzZWQgZm9yIGRvaW5nIGluZmVyZW5jZSB3aXRoIHRoZSBvY2N1cnJlbmNlIGJpcnRoLWRlYXRoIG1vZGVsLgoKIyMjIENvbXBhcmUgd2l0aCBhIFBvaXNzb24gc2FtcGxpbmcgcHJvY2VzcwoKSW4gb3JkZXIgdG8gY2hlY2sgaWYgdGhlIGRhdGEgZml0IG91ciBhc3N1bXB0aW9ucyBvZiBjb25zdGFudC1mb3NzaWxpemF0aW9uLXJhdGUgUG9pc3NvbiBzYW1wbGluZyB3ZSBjb21wYXJlIHRoZSBvYnNlcnZlZCBvY2N1cnJlbmNlcyBkaXN0cmlidXRpb25zIHdpdGggdGhlIGV4cGVjdGVkIG9uZXMuIFNwZWNpZmljYWxseSwgd2Ugd2lsbCBsb29rIGF0IHRoZSBudW1iZXIgb2YgdGF4YSByZXByZXNlbnRlZCBieSAxLCAyLCAzLCAuLi4gb2NjdXJyZW5jZXMgYW5kIHRoZSBvbmUgdGhhdCB3ZSB3b3VsZCBleHBlY3QgZm9yIGEgZ2l2ZW4gZGlzdHJpYnV0aW9uIG9mIHN0cmF0aWdyYXBoaWMgcmFuZ2VzIChzZWVuIGhlcmUgYXMgYSBwcm94eSBmb3Igc3BlY2llcyBkdXJhdGlvbikuCgpgYGB7ciwgZmlnLmFzcD0wLjUsIGZpZy53aWR0aD0xMH0KY29uZGl0aW9ucyA8LSAhKENldGFjZWFfb2NjJGFjY2VwdGVkX3JhbmsgJWluJSBjKCJzdWJzcGVjaWVzIiwgImluZnJhb3JkZXIiKSkgJiBDZXRhY2VhX29jYyRhZ2VfdW5jZXJ0YWludHk8MTAKCmdncGxvdChDZXRhY2VhX29jY1tjb25kaXRpb25zLF0sIGFlcyh4PXN0cmF0aWdyYXBoaWNfcmFuZ2VfZHVyYXRpb24sIGZpbGw9YWNjZXB0ZWRfcmFuaykpICsKICBnZW9tX2hpc3RvZ3JhbShiaW53aWR0aCA9IDEpICsgCiAgI2dlb21fcG9pbnQoKSArCiAgc2NhbGVfeF9jb250aW51b3VzKG5hbWUgPSAiQWdlIHJhbmdlIChNeSkiKSArCiAgI3NjYWxlX3lfY29udGludW91cyh0cmFucyA9ICJsb2cxMCIsIG5hbWUgPSAiQ291bnQgKGxvZy1zY2FsZSkiKSArCiAgc2NhbGVfZmlsbF9kaXNjcmV0ZShuYW1lPSJBY2NlcHRlZCByYW5rIikgKwogIHRoZW1lKHBhbmVsLmdyaWQubWFqb3IueCA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBsZWdlbmQucG9zaXRpb249ImJvdHRvbSIpICsKICBnZ3RpdGxlKCJPYnNlcnZlZCBkaXN0cmlidXRpb25zIG9mIHN0cmF0aWdyYXBoaWMgcmFuZ2VzIikgKwogIGZhY2V0X2dyaWQoLiB+IGFjY2VwdGVkX3JhbmssIHNjYWxlcyA9ICJmcmVlIikKCmdncGxvdChDZXRhY2VhX29jY1tjb25kaXRpb25zLF0sIGFlcyh4PWFjY2VwdGVkX25hbWVfY291bnQsIHk9KHRhYmxlKGFjY2VwdGVkX25hbWVfY291bnQpL2FzLm51bWVyaWMobmFtZXModGFibGUoYWNjZXB0ZWRfbmFtZV9jb3VudCkpKSlbYXMuZmFjdG9yKGFjY2VwdGVkX25hbWVfY291bnQpXSwgY29sPWFjY2VwdGVkX3JhbmspKSArCiAgZ2VvbV9wb2ludCgpICsKICBzY2FsZV94X2NvbnRpbnVvdXModHJhbnMgPSAibG9nMTAiLCBuYW1lID0gIk51bWJlciBvZiBvY2N1cnJlbmNlcyBieSBhY2NlcHRlZCBuYW1lIChsb2ctc2NhbGUpIikgKwogIHNjYWxlX3lfY29udGludW91cyh0cmFucyA9ICJsb2cxMCIsIG5hbWUgPSAiTnVtYmVyIG9mIGNvcnJlc3BvbmRpbmcgYWNjZXB0ZWQgbmFtZXMgKGxvZy1zY2FsZSkiKSArCiAgc2NhbGVfZmlsbF9kaXNjcmV0ZShuYW1lPSJBY2NlcHRlZCByYW5rIikgKwogIHRoZW1lKHBhbmVsLmdyaWQubWFqb3IueCA9IGVsZW1lbnRfYmxhbmsoKSwgCiAgICAgICAgcGFuZWwuZ3JpZC5tYWpvci55ID0gZWxlbWVudF9ibGFuaygpKSArCiAgZ2d0aXRsZSgiT2JzZXJ2ZWQgZGlzdHJpYnV0aW9ucyBvZiB0aGUgbnVtYmVyIG9mIGFjY2VwdGVkIG5hbWVzIHdpdGggdGhlIHNhbWUgbnVtYmVyIG9mIG9jY3VycmVuY2VzIikgKwogIGZhY2V0X2dyaWQoYWNjZXB0ZWRfcmFuayB+IC4sIHNjYWxlcyA9ICJmcmVlIikKYGBgCgpJbiBhIFBvaXNzb24gcHJvY2VzcyB3aXRoIG9jY3VycmVuY2Ugc2FtcGxpbmcgcmF0ZSAkXG9tZWdhJCBhbmQgZm9yIGEgZ2l2ZW4gdGltZSBpbnRlcnZhbCBvZiBsZW5ndGggJHQkLCB0aGUgcHJvYmFiaWxpdHkgb2Ygb2JzZXJ2aW5nICROX3QgPSBrJCBvY2N1cnJlbmNlcyBpcyBnaXZlbiBieSB0aGUgUG9pc3NvbiBkaXN0cmlidXRpb24gb2YgbWVhbiBvZiBwYXJhbWV0ZXIgJFxvbWVnYVx0aW1lcyB0JDogCgokJFxtYXRoYmJ7UH0oTl90PWspID0gZV57LVxvbWVnYSB0fVxmcmFjeyhcb21lZ2EgdClea317ayF9JCQKClNvIGluIG9yZGVyIHRvIGhhdmUgdGhlIGFic29sdXRlIHByb2JhYmlsaXR5IG9mIG9ic2VydmluZyAkTl8wID0gbiQgb2NjdXJyZW5jZXMgd2UgaGF2ZSB0byBpbnRlZ3JhdGUgb3ZlciB0aGUgZnVsbCBkaXN0cmlidXRpb24gb2YgYWdlIHVuY2VydGFpbnRpZXMgJHQkLCBjYWxsZWQgJGYodCkkOgoKJCRcbWF0aGJie1B9KE5fMCA9IG4pID0gXGludF90IFAoTl90ID0gbikgZih0KSBkdCA9IFxpbnRfdCBlXnstXG9tZWdhIHR9XGZyYWN7KFxvbWVnYSB0KV5ufXtuIX0gZih0KSBkdCQkCgpGaXJzdCwgIGFwcHJveGltYXRlIHRoaXMgZGlzdHJpYnV0aW9uOgoKYGBge3J9CnJhbmdlX2RlbnNpdHkgPC0gYXBwcm94ZnVuKGRlbnNpdHkoQ2V0YWNlYV9vY2NbQ2V0YWNlYV9vY2MkYWNjZXB0ZWRfcmFuaz09InNwZWNpZXMiLF0kc3RyYXRpZ3JhcGhpY19yYW5nZV9kdXJhdGlvbltpcy5maW5pdGUoQ2V0YWNlYV9vY2NbQ2V0YWNlYV9vY2MkYWNjZXB0ZWRfcmFuaz09InNwZWNpZXMiLF0kc3RyYXRpZ3JhcGhpY19yYW5nZV9kdXJhdGlvbildKSkKCmhpc3QoQ2V0YWNlYV9vY2NbQ2V0YWNlYV9vY2MkYWNjZXB0ZWRfcmFuaz09InNwZWNpZXMiLF0kc3RyYXRpZ3JhcGhpY19yYW5nZV9kdXJhdGlvbiwgcHJvYmFiaWxpdHkgPSBULCBicmVha3MgPSAyMCwgbWFpbj0iRGVuc2l0eSBhcHByb3hpbWF0aW9uIG9mIHRoZSBlbXBpcmljYWwgc3RyYXRpZ3JhcGhpYyByYW5nZSBkaXN0cmlidXRpb24iLCB4bGFiID0gIkFnZSByYW5nZSAoTXkpIikKbGluZXMoMToxMDAvNSwgcmFuZ2VfZGVuc2l0eSgxOjEwMC81KSkKYGBgCgpUaGVuIGludGVncmF0ZSBhbmQgcGxvdCB0aGUgZXhwZWN0ZWQgZGlzdHJpYnV0aW9uIGZvciBhIGdpdmVuIG9tZWdhOgoKYGBge3IgZmlnLmFzcD0wLjMsIGZpZy53aWR0aD0xMX0KZXhwZWN0ZWRfZGlzdHJpYnV0aW9uIDwtIGZ1bmN0aW9uKG4sIG9tZWdhLCBzdHJhdGlncmFwaGljX3JhbmdlX2R1cmF0aW9uKXsKICByYW5nZV9kZW5zaXR5IDwtIGFwcHJveGZ1bihkZW5zaXR5KHN0cmF0aWdyYXBoaWNfcmFuZ2VfZHVyYXRpb25baXMuZmluaXRlKHN0cmF0aWdyYXBoaWNfcmFuZ2VfZHVyYXRpb24pXSkpCiAgZyA8LSBmdW5jdGlvbih0KXtkcG9pcyhuLCBvbWVnYSp0KSpyYW5nZV9kZW5zaXR5KHQpfQogIHJldHVybiAoaW50ZWdyYXRlKGcsIGxvd2VyID0gMSwgdXBwZXIgPSBtYXgoc3RyYXRpZ3JhcGhpY19yYW5nZV9kdXJhdGlvbikpKQp9CgpvbWVnYSA8LSAwLjEKCmRlbnMgPC0gc2FwcGx5KDA6MjAsIGZ1bmN0aW9uKG4pe2V4cGVjdGVkX2Rpc3RyaWJ1dGlvbihuLCBvbWVnYSwgQ2V0YWNlYV9vY2NbQ2V0YWNlYV9vY2MkYWNjZXB0ZWRfcmFuaz09InNwZWNpZXMiLF0kc3RyYXRpZ3JhcGhpY19yYW5nZV9kdXJhdGlvbikkdmFsdWV9KQoKcGxvdCgwOjIwLCBkZW5zLCBtYWluPSJFeHBlY3RlZCBkaXN0cmlidXRpb24gb2YgdGhlIG51bWJlciBvZiBhY2NlcHRlZCBuYW1lcyB3aXRoIHRoZSBzYW1lIG51bWJlciBvZiBvY2N1cnJlbmNlcyIsIHhsYWI9Ik51bWJlciBvZiBvY2N1cnJlbmNlcyB3aXRoIHRoZSBzYW1lIGFjY2VwdGVkIG5hbWUiLCB5bGFiID0gIlByb3BvcnRpb25zIiwgdHlwZSA9ICJiIikKYGBgCgpGaW5hbGx5LCB0cnkgdG8gZmluZCBhbiAkXG9tZWdhJCB2YWx1ZSB0aGF0IGFwcHJveGltYXRlbHkgZml0cyB0aGUgZmlyc3QgcG9pbnRzICh0aGUgbGVhc3QgYWZmZWN0ZWQgYnkgb3ZlcnNhbXBsaW5nIGJpYXNlcykgYW5kIGNoZWNrIGlmIHRoZSBvdGhlciBwb2ludHMgZm9sbG93IHRoZSBleHBlY3RlZCBjdXJ2ZToKCmBgYHtyIGZpZy53aWR0aD0xMCwgZmlnLmFzcD0wLjR9CiMgUmVjb3VudCB0aGUgbnVtYmVyIG9mIG9jY3VycmVuY2VzIHdpdGggdGhlIHNhbWUgYWNjZXB0ZWQgbmFtZSBhZnRlciB0aGUgc2FtcGxpbmcKQ2V0YWNlYV9vY2Nfc2FtcGxlZCRhY2NlcHRlZF9uYW1lX2NvdW50IDwtIHNhcHBseShDZXRhY2VhX29jY19zYW1wbGVkJGFjY2VwdGVkX25hbWUsIGZ1bmN0aW9uKHgpe3RhYmxlKENldGFjZWFfb2NjX3NhbXBsZWQkYWNjZXB0ZWRfbmFtZSlbeF19KQoKb21lZ2EgPC0gMC4xCmFjY2VwdGVkX25hbWVfY291bnRfc3BlY2llcyA8LSBDZXRhY2VhX29jY1tDZXRhY2VhX29jYyRhY2NlcHRlZF9yYW5rPT0ic3BlY2llcyIsXSRhY2NlcHRlZF9uYW1lX2NvdW50CmRlbnMgPC0gc2FwcGx5KDE6bWF4KGFjY2VwdGVkX25hbWVfY291bnRfc3BlY2llcyksIGZ1bmN0aW9uKG4peyBleHBlY3RlZF9kaXN0cmlidXRpb24obiwgb21lZ2EsIENldGFjZWFfb2NjW0NldGFjZWFfb2NjJGFjY2VwdGVkX3Jhbms9PSJzcGVjaWVzIixdJHN0cmF0aWdyYXBoaWNfcmFuZ2VfZHVyYXRpb24pJHZhbHVlIH0pCmFjY2VwdGVkX25hbWVfY291bnRfY2F0ZWdvcmllcyA8LSB0YWJsZShhY2NlcHRlZF9uYW1lX2NvdW50X3NwZWNpZXMpL2FzLm51bWVyaWMobmFtZXModGFibGUoYWNjZXB0ZWRfbmFtZV9jb3VudF9zcGVjaWVzKSkpICAjIE51bWJlciBvZiBjYXRlZ29yaWVzIHdpdGggMSwgMiwgMywgLi4uIG9jY3VycmVuY2VzIG9mIHRoZSBzYW1lIHNwZWNpZXMKCiMgQ29tcGFyZSB0aGUgaW5pdGlhbCBvYnNlcnZlZCBkaXN0cmlidXRpb24gd2l0aCB0aGUgdGhlb3JldGljYWwgY3VydmUKZ2dwbG90KENldGFjZWFfb2NjW0NldGFjZWFfb2NjJGFjY2VwdGVkX3Jhbms9PSJzcGVjaWVzIixdLAogICAgICAgYWVzKHg9YWNjZXB0ZWRfbmFtZV9jb3VudCwgCiAgICAgICAgICAgeT1hY2NlcHRlZF9uYW1lX2NvdW50X2NhdGVnb3JpZXNbYXMuZmFjdG9yKGFjY2VwdGVkX25hbWVfY291bnQpXSwgCiAgICAgICAgICAgZmlsbD1hY2NlcHRlZF9yYW5rKSkgKwogIGdlb21fcG9pbnQoKSArCiAgCiAgYW5ub3RhdGUoImxpbmUiLCB4ID0gMTptYXgoYWNjZXB0ZWRfbmFtZV9jb3VudF9zcGVjaWVzKSwgeT0gZGVucwogICAgKm1heChhY2NlcHRlZF9uYW1lX2NvdW50X2NhdGVnb3JpZXNbYXMuZmFjdG9yKGFjY2VwdGVkX25hbWVfY291bnRfc3BlY2llcyldKSAvbWF4KGRlbnMpKSsKICAKICBzY2FsZV94X2NvbnRpbnVvdXMobmFtZSA9ICJOdW1iZXIgb2Ygb2NjdXJyZW5jZXMgYnkgYWNjZXB0ZWQgbmFtZSIpICsKICBzY2FsZV95X2NvbnRpbnVvdXModHJhbnMgPSAibG9nMTAiLCBuYW1lID0gIk51bWJlciBvZiBjb3JyZXNwb25kaW5nIGFjY2VwdGVkIG5hbWVzIChsb2ctc2NhbGUpIikgKwogIHNjYWxlX2ZpbGxfZGlzY3JldGUobmFtZT0iT2JzZXJ2ZWQgZGlzdHJpYnV0aW9uIikgKwogIHRoZW1lKHBhbmVsLmdyaWQubWFqb3IueCA9IGVsZW1lbnRfYmxhbmsoKSwgCiAgICAgICAgcGFuZWwuZ3JpZC5tYWpvci55ID0gZWxlbWVudF9ibGFuaygpKSArCiAgZ2d0aXRsZSgiQ29tcGFyaXNvbiBiZXR3ZWVuIGV4cGVjdGVkIGFuZCBvYnNlcnZlZCBkaXN0cmlidXRpb25zIG9mIG51bWJlciBvZiBvY2N1cnJlbmNlcyIpICsKICBmYWNldF9ncmlkKGFjY2VwdGVkX3JhbmsgfiAuLCBzY2FsZXMgPSAiZnJlZSIpCgphY2NlcHRlZF9uYW1lX2NvdW50X3NwZWNpZXNfc2FtcGxlZCA8LSBDZXRhY2VhX29jY19zYW1wbGVkW0NldGFjZWFfb2NjX3NhbXBsZWQkYWNjZXB0ZWRfcmFuaz09InNwZWNpZXMiLF0kYWNjZXB0ZWRfbmFtZV9jb3VudApkZW5zX3NhbXBsZWQgPC0gc2FwcGx5KDE6bWF4KGFjY2VwdGVkX25hbWVfY291bnRfc3BlY2llc19zYW1wbGVkKSwgZnVuY3Rpb24obil7CiAgICAgZXhwZWN0ZWRfZGlzdHJpYnV0aW9uKG4sIG9tZWdhLCBDZXRhY2VhX29jY19zYW1wbGVkW0NldGFjZWFfb2NjX3NhbXBsZWQkYWNjZXB0ZWRfcmFuaz09InNwZWNpZXMiLF0kc3RyYXRpZ3JhcGhpY19yYW5nZV9kdXJhdGlvbikkdmFsdWUKICAgIH0pCmFjY2VwdGVkX25hbWVfY291bnRfY2F0ZWdvcmllc19zYW1wbGVkIDwtIHRhYmxlKGFjY2VwdGVkX25hbWVfY291bnRfc3BlY2llc19zYW1wbGVkKS9hcy5udW1lcmljKG5hbWVzKHRhYmxlKGFjY2VwdGVkX25hbWVfY291bnRfc3BlY2llc19zYW1wbGVkKSkpICAjIE51bWJlciBvZiBjYXRlZ29yaWVzIHdpdGggMSwgMiwgMywgLi4uIG9jY3VycmVuY2VzIG9mIHRoZSBzYW1lIHNwZWNpZXMKCiMgQ29tcGFyZSB0aGUgY29ycmVjdGVkIG9ic2VydmVkIGRpc3RyaWJ1dGlvbiB3aXRoIHRoZSB0aGVvcmV0aWNhbCBjdXJ2ZQpnZ3Bsb3QoQ2V0YWNlYV9vY2Nfc2FtcGxlZFtDZXRhY2VhX29jY19zYW1wbGVkJGFjY2VwdGVkX3Jhbms9PSJzcGVjaWVzIixdLCAKICAgICAgIGFlcyh4PWFjY2VwdGVkX25hbWVfY291bnQsCiAgICAgICAgICAgeT1hY2NlcHRlZF9uYW1lX2NvdW50X2NhdGVnb3JpZXNfc2FtcGxlZFthcy5mYWN0b3IoYWNjZXB0ZWRfbmFtZV9jb3VudCldLAogICAgICAgICAgIGZpbGw9YWNjZXB0ZWRfcmFuaykpICsKICBnZW9tX3BvaW50KCkgKwogIAogIGFubm90YXRlKCJsaW5lIiwgeCA9IDE6bWF4KGFjY2VwdGVkX25hbWVfY291bnRfc3BlY2llc19zYW1wbGVkKSwgeT0gZGVuc19zYW1wbGVkCiAgICAqbWF4KGFjY2VwdGVkX25hbWVfY291bnRfY2F0ZWdvcmllc19zYW1wbGVkW2FzLmZhY3RvcihhY2NlcHRlZF9uYW1lX2NvdW50X3NwZWNpZXNfc2FtcGxlZCldKSAvbWF4KGRlbnNfc2FtcGxlZCkpICsKICAKICBzY2FsZV94X2NvbnRpbnVvdXMobmFtZSA9ICJOdW1iZXIgb2Ygb2NjdXJyZW5jZXMgYnkgYWNjZXB0ZWQgbmFtZSIpICsKICBzY2FsZV95X2NvbnRpbnVvdXModHJhbnMgPSAibG9nMTAiLCBuYW1lID0gIk51bWJlciBvZiBjb3JyZXNwb25kaW5nIGFjY2VwdGVkIG5hbWVzIChsb2ctc2NhbGUpIikgKwogIHNjYWxlX2ZpbGxfZGlzY3JldGUobmFtZT0iT2JzZXJ2ZWQgZGlzdHJpYnV0aW9uIikgKwogIHRoZW1lKHBhbmVsLmdyaWQubWFqb3IueCA9IGVsZW1lbnRfYmxhbmsoKSwgCiAgICAgICAgcGFuZWwuZ3JpZC5tYWpvci55ID0gZWxlbWVudF9ibGFuaygpKSArCiAgZ2d0aXRsZSgiQ29tcGFyaXNvbiBiZXR3ZWVuIGV4cGVjdGVkIGFuZCBvYnNlcnZlZCBkaXN0cmlidXRpb25zIG9mIG51bWJlciBvZiBvY2N1cnJlbmNlcywgYWZ0ZXIgc2FtcGxpbmciKSArCiAgZmFjZXRfZ3JpZChhY2NlcHRlZF9yYW5rIH4gLiwgc2NhbGVzID0gImZyZWUiKQpgYGAKCiRcaW1wbGllcyQgSW5pdGlhbCBvYnNlcnZhdGlvbnMgcmVhbGx5IGRvIG5vdCBmaXQgdGhlIGV4cGVjdGF0aW9ucywgKipzcGVjaWVzIHdpdGggbW9yZSB0aGFuIDUgb2NjdXJyZW5jZXMgbXVzdCByZW1haW4gdmVyeSByYXJlKiogISBCdXQgb3VyIHN1YnNhbXBsaW5nIHNlZW1zIHRvIGNvcnJlY3QgbW9zdCBvZiB0aGlzIGJpYXMuCgpIb3dldmVyLCB0aGlzIG1ldGhvZCByZXF1aXJlcyB0byBtYWtlIHNldmVyYWwgYXJiaXRyYXJ5IGNob2ljZXMgdGhhdCBtYXkgaW50cm9kdWNlIG5ldyBiaWFzZXMgc28gd2Ugd2lsbCBpbnN0ZWFkIHN1YnNhbXBsZSBhdCBvdGhlciBsZXZlbHMgKHBhbGFlb250b2xvZ2ljYWwgY29sbGVjdGlvbiwgZ2VvbG9naWNhbCBmb3JtYXRpb24pLiBJbiBlYWNoIGNhc2Ugb25seSBvbmUgb2NjdXJyZW5jZSB3aWxsIGJlIHNhbXBsZWQgZm9yIHRoZSBzaW1pbGFybHkgaWRlbnRpZmllZCwgYSBwcm9jZXNzIHdlIHdpbGwgcmVmZXIgdG8gYXMgKiphZ2dyZWdhdGluZyoqIHRoZXNlIG9jY3VycmVuY2VzIGFjY29yZGluZyB0byB0aGUgY2hvc2VuIGZhY3Rvci4KCiMjIEJJQVMgQ09SUkVDVElPTiBOwrAzYmlzOiBTdWJzYW1wbGUgb2NjdXJyZW5jZXMgYnkgYWdncmVnYXRpbmcgc2ltaWxhcmx5IGlkZW50aWZpZWQgb2NjdXJyZW5jZXMgaW4gZWFjaCBjb2xsZWN0aW9uCgoqKlN1YnNhbXBsaW5nIGJ5IGFnZ3JlZ2F0aW9uKiogPSBhZ2dyZWdhdGUgYWxsIHRoZSBvY2N1cnJlbmNlcyBvZiBhIGdpdmVuIHRheG9uIGFjY29yZGluZyB0byBhIGdpdmVuIGNyaXRlcmlvbiAoY29sbGVjdGlvbiwgZ2VvbG9naWNhbCBmb3JtYXRpb24sIGNvdW50cnksIGdlb2xvZ2ljYWwgcGxhdGUpLgoKIyMgV3JvbmcgdHJhY2s6IEFnZ3JlZ2F0ZSBzaW1pbGFybHkgaWRlbnRpZmllZCBvY2N1cnJlbmNlcyBpbiBlYWNoIGNvbGxlY3Rpb24KCkluIG9yZGVyIHRvIHJlZHVjZSB0aGUgYWJ1bmRhbmNlIGJpYXMsIHdlIG1heSBrZWVwIG9ubHkgb25lIG9jY3VycmVuY2UgZm9yIGVhY2ggY29sbGVjdGlvbjoKCmBgYHtyfQpDZXRhY2VhX29jY19hZ2dyZWcgPC0gYygpCgojIEJyb3dzZSBhbGwgY29sbGVjdGlvbnMKY29sbGVjdGlvbnMgPC0gbGV2ZWxzKGRyb3BsZXZlbHMoQ2V0YWNlYV9vY2MkY29sbGVjdGlvbl9ubykpCmZvciAoY29sbCBpbiBjb2xsZWN0aW9ucyl7CiAgQ2V0YWNlYV9vY2NfY29sbCA8LSBDZXRhY2VhX29jY1tDZXRhY2VhX29jYyRjb2xsZWN0aW9uX25vPT1jb2xsLF0KICAKICAjIEJyb3dzZSBhbGwgYWNjZXB0ZWQgbmFtZXMgaW4gZWFjaCBjb2xsZWN0aW9uICYgc2FtcGxlIG9ubHkgMSBvY2N1cnJlbmNlCiAgdGF4YSA8LSBsZXZlbHMoZHJvcGxldmVscyhDZXRhY2VhX29jY19jb2xsJGFjY2VwdGVkX25hbWUpKQogIGZvciAobmFtZSBpbiB0YXhhKXsKICAgIENldGFjZWFfb2NjX2FnZ3JlZyA8LSByYmluZChDZXRhY2VhX29jY19hZ2dyZWcsIHNhbXBsZV9uKENldGFjZWFfb2NjX2NvbGxbQ2V0YWNlYV9vY2NfY29sbCRhY2NlcHRlZF9uYW1lPT1uYW1lLF0sIHNpemUgPSAxKSkKICB9Cn0KCmRhdGEuZnJhbWUoQ2V0YWNlYV9vY2MgPSBjKGRpbShDZXRhY2VhX29jYylbMV0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGRpbShDZXRhY2VhX29jY1tDZXRhY2VhX29jYyRhY2NlcHRlZF9yYW5rID09InNwZWNpZXMiLF0pWzFdKSwKICAgICAgICAgICBDZXRhY2VhX29jY19hZ2dyZWcgPSBjKGRpbShDZXRhY2VhX29jY19hZ2dyZWcpWzFdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGltKENldGFjZWFfb2NjX2FnZ3JlZ1tDZXRhY2VhX29jY19hZ2dyZWckYWNjZXB0ZWRfcmFuayA9PSJzcGVjaWVzIixdKVsxXSksCiAgICAgICAgICAgcmVtb3ZlZCA9IGMoZGltKENldGFjZWFfb2NjKVsxXS1kaW0oQ2V0YWNlYV9vY2NfYWdncmVnKVsxXSwKICAgICAgICAgICAgICAgICAgICAgICBkaW0oQ2V0YWNlYV9vY2NbQ2V0YWNlYV9vY2MkYWNjZXB0ZWRfcmFuayA9PSJzcGVjaWVzIixdKVsxXS1kaW0oQ2V0YWNlYV9vY2NfYWdncmVnW0NldGFjZWFfb2NjX2FnZ3JlZyRhY2NlcHRlZF9yYW5rID09InNwZWNpZXMiLF0pWzFdKSwKICAgICAgICAgICByb3cubmFtZXMgPSBjKCJOdW1iZXIgb2Ygb2NjdXJyZW5jZXMiLCAiTnVtYmVyIG9mIG9jY3VycmVuY2VzIChzcGVjaWVzIG9ubHkpIikpCmBgYAoKJFx0byQgTm90IGVub3VnaCBvY2N1cnJlbmNlcyBhcmUgcmVtb3ZlZCB0byBtYWtlIGEgc3VmZmljaWVudCBkaWZmZXJlbmNlLiBJZiB3ZSBsb29rIGF0IHRoZSBjb2xsZWN0aW9uIHdpdGggdGhlIGhpZ2hlc3QgbnVtYmVyIG9mIG9jY3VycmVuY2VzOgoKYGBge3J9CmNvbGxlY3Rpb25fbWF4X29jY3VycmVuY2VzIDwtIG1heCh0YWJsZShDZXRhY2VhX29jYyRjb2xsZWN0aW9uX25vKVtDZXRhY2VhX29jYyRjb2xsZWN0aW9uX25vXSkKY29sbGVjdGlvbl9tYXhfbm8gPC0gbmFtZXModGFibGUoQ2V0YWNlYV9vY2MkY29sbGVjdGlvbl9ubylbQ2V0YWNlYV9vY2MkY29sbGVjdGlvbl9ub11bdGFibGUoQ2V0YWNlYV9vY2MkY29sbGVjdGlvbl9ubylbQ2V0YWNlYV9vY2MkY29sbGVjdGlvbl9ub109PWNvbGxlY3Rpb25fbWF4X29jY3VycmVuY2VzXVsxXSkKCnRhYmxlKGRyb3BsZXZlbHMoQ2V0YWNlYV9vY2NbQ2V0YWNlYV9vY2MkY29sbGVjdGlvbl9ubz09Y29sbGVjdGlvbl9tYXhfbm8sXSRhY2NlcHRlZF9uYW1lKSkKYGBgCgokXHRvJCBUaGVyZSBhcmUgdmVyeSBmZXcgcmVkdW5kYW5jaWVzIGFtb25nIHRoZSBhY2NlcHRlZCBuYW1lcyBpbiBjb2xsZWN0aW9ucyBzbyBhZ2dyZWdhdGluZyB0aG9zZSB3b24ndCByZWR1Y2UgdGhlIGFidW5kYW5jZSBiaWFzLgoKSW5zdGVhZCwgd2UgbWF5IHRyeSB0byAqKmFnZ3JlZ2F0ZSBvY2N1cnJlbmNlcyB3aXRoIHRoZSBzYW1lIGFjY2VwdGVkIG5hbWUgYXQgdGhlIGxldmVsIG9mIHRoZSBnZW9sb2dpY2FsIGZvcm1hdGlvbioqIChpZSBzdWJzYW1wbGUgb25seSBvbmUgZm9yIGVhY2gpLgoKIyMgQWdncmVnYXRlIHNpbWlsYXJseSBpZGVudGlmaWVkIG9jY3VycmVuY2VzIGluIGVhY2ggZm9ybWF0aW9uCgpgYGB7ciBmaWcuaGVpZ2h0PTgsIGluY2x1ZGU9Rn0KQ2V0YWNlYV9vY2Nfc3BlY2llcyA8LSBDZXRhY2VhX29jY1tDZXRhY2VhX29jYyRhY2NlcHRlZF9yYW5rPT0ic3BlY2llcyIsXQoKIyBCcm93c2UgYWxsIG51bWJlcnMgb2Ygb2NjdXJyZW5jZXMgYnkgZm9ybWF0aW9uCmZvcm1hdGlvbl9vY2N1cnJlbmNlc19uYiA8LSBhcy5udW1lcmljKG5hbWVzKHRhYmxlKHRhYmxlKGRyb3BsZXZlbHMoQ2V0YWNlYV9vY2Nfc3BlY2llcyRmb3JtYXRpb24pKSkpKQoKZm9yIChuIGluIGxpc3QoYyg0LCA3KSwgYyg4LCAxNSksIGMoMTYsIDEyNCkpKXsKICBBIDwtIENldGFjZWFfb2NjX3NwZWNpZXNbYXMubG9naWNhbCh0YWJsZShDZXRhY2VhX29jY19zcGVjaWVzJGZvcm1hdGlvbilbQ2V0YWNlYV9vY2Nfc3BlY2llcyRmb3JtYXRpb25dPj1uWzFdKQogICAgICAgICAgICAgICAgICAgICAgICAgICAmIGFzLmxvZ2ljYWwodGFibGUoQ2V0YWNlYV9vY2Nfc3BlY2llcyRmb3JtYXRpb24pW0NldGFjZWFfb2NjX3NwZWNpZXMkZm9ybWF0aW9uXTw9blsyXSksXQogIEEkZm9ybWF0aW9uIDwtIGRyb3BsZXZlbHMoQSRmb3JtYXRpb24pCgogIHAgPC0gZ2dwbG90KEEsIGFlcyh4PS1hZ2VfbWVhbiwgZmlsbD1hY2NlcHRlZF9uYW1lKSkgKwogICAgZ2VvbV9oaXN0b2dyYW0oYmlud2lkdGggPSAwLjUsIGNvbD0iYmxhY2siKSArCiAgICBzY2FsZV94X2NvbnRpbnVvdXMobmFtZSA9ICJUaW1lIChNeSkiKSArCiAgICBzY2FsZV95X2NvbnRpbnVvdXMobmFtZSA9ICJOdW1iZXIgb2Ygb2NjdXJyZW5jZXMgaW4gdGhlIGZvcm1hdGlvbiIpICsKICAgIHNjYWxlX2ZpbGxfZGlzY3JldGUobmFtZT0iQWNjZXB0ZWQgbmFtZSIpICsKICAgIHRoZW1lKHBhbmVsLmdyaWQubWFqb3IueSA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikgKwogICAgZ2d0aXRsZShwYXN0ZSgiRGlzdHJpYnV0aW9uIG9mIG9jY3VycmVuY2VzJyBtZWFuIGFnZSBmb3IgZm9ybWF0aW9ucyB3aXRoIiwgblsxXSwgIi0iLCBuWzJdLCAib2NjdXJyZW5jZXMgKGNvbG9yZWQgYnkgc3BlY2llcykiKSkgKwogICAgZmFjZXRfZ3JpZChmb3JtYXRpb24gfiAuLCBzY2FsZXM9ImZyZWUiKQogIHByaW50KHApCn0KCm1heF9zcGVjaWVzX2J5X2Zvcm1hdGlvbiA8LSBtYXgodGFibGUoQ2V0YWNlYV9vY2Nfc3BlY2llcyRmb3JtYXRpb24pKQpBIDwtIENldGFjZWFfb2NjX3NwZWNpZXNbYXMubG9naWNhbCh0YWJsZShDZXRhY2VhX29jY19zcGVjaWVzJGZvcm1hdGlvbilbQ2V0YWNlYV9vY2Nfc3BlY2llcyRmb3JtYXRpb25dPT1tYXhfc3BlY2llc19ieV9mb3JtYXRpb24pLF0KQSRmb3JtYXRpb24gPC0gZHJvcGxldmVscyhBJGZvcm1hdGlvbikKCmdncGxvdChBLCBhZXMoeD0tYWdlX21lYW4sIGZpbGw9cmVvcmRlcihhY2NlcHRlZF9uYW1lLCAtYWdlX21lYW4pKSkgKwogIGdlb21faGlzdG9ncmFtKGJpbndpZHRoID0gMC41LCBjb2w9ImJsYWNrIikgKwogIHNjYWxlX3hfY29udGludW91cyhuYW1lID0gIlRpbWUgKE15KSIpICsKICBzY2FsZV95X2NvbnRpbnVvdXMobmFtZSA9ICJOdW1iZXIgb2Ygb2NjdXJyZW5jZXMgaW4gdGhlIGZvcm1hdGlvbiIpICsKICBzY2FsZV9maWxsX2Rpc2NyZXRlKG5hbWU9IkFjY2VwdGVkIG5hbWUiKSArCiAgdGhlbWUocGFuZWwuZ3JpZC5tYWpvci55ID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikgKwogIGdndGl0bGUocGFzdGUoIkRpc3RyaWJ1dGlvbiBvZiBvY2N1cnJlbmNlcycgbWVhbiBhZ2UgZm9yIiwgbWF4X3NwZWNpZXNfYnlfZm9ybWF0aW9uLCAib2NjdXJyZW5jZXMgd2l0aG91dCBpbmRpY2F0ZWQgZm9ybWF0aW9uIChjb2xvcmVkIGJ5IHNwZWNpZXMpIikpICsKICBmYWNldF9ncmlkKGZvcm1hdGlvbiB+IC4pCgojICRcdG8kIEZvciBtb3N0IGZvcm1hdGlvbnMgZWFjaCBzcGVjaWVzIHNlZW1zIHRvIGJlIHJlc3RyaWN0ZWQgdG8gb25seSBvbmUgYWdlLCBzbyBhcyBleHBlY3RlZCB3ZSBhcmUgbm90IGxvb3NpbmcgdG9vIG11Y2ggaW5mb3JtYXRpb24gd2hlbiBhZ2dyZWdhdGluZyB0aGVtIHRvIGEgc2luZ2xlIG9jY3VycmVuY2UuCmBgYAoKYGBge3J9CkNldGFjZWFfb2NjX2FnZ3JlZyA8LSBjKCkKCiMgQnJvd3NlIGFsbCBmb3JtYXRpb25zCmZvcm1hdGlvbnMgPC0gbGV2ZWxzKGRyb3BsZXZlbHMoQ2V0YWNlYV9vY2MkZm9ybWF0aW9uKSkKZm9yIChmb3JtIGluIGZvcm1hdGlvbnMpewogIENldGFjZWFfb2NjX2Zvcm0gPC0gQ2V0YWNlYV9vY2NbQ2V0YWNlYV9vY2MkZm9ybWF0aW9uPT1mb3JtLF0KICAKICAjIEJyb3dzZSBhbGwgYWNjZXB0ZWQgbmFtZXMgaW4gZWFjaCBmb3JtYXRpb24gJiBzYW1wbGUgb25seSAxIG9jY3VycmVuY2UKICB0YXhhIDwtIGxldmVscyhkcm9wbGV2ZWxzKENldGFjZWFfb2NjX2Zvcm0kYWNjZXB0ZWRfbmFtZSkpCiAgZm9yIChuYW1lIGluIHRheGEpewogICAgQ2V0YWNlYV9vY2NfYWdncmVnIDwtIHJiaW5kKENldGFjZWFfb2NjX2FnZ3JlZywgc2FtcGxlX24oQ2V0YWNlYV9vY2NfZm9ybVtDZXRhY2VhX29jY19mb3JtJGFjY2VwdGVkX25hbWU9PW5hbWUsXSwgc2l6ZSA9IDEpKQogIH0KfQoKZGF0YS5mcmFtZShDZXRhY2VhX29jYyA9IGMoZGltKENldGFjZWFfb2NjKVsxXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgZGltKENldGFjZWFfb2NjW0NldGFjZWFfb2NjJGFjY2VwdGVkX3JhbmsgPT0ic3BlY2llcyIsXSlbMV0pLAogICAgICAgICAgIENldGFjZWFfb2NjX2FnZ3JlZyA9IGMoZGltKENldGFjZWFfb2NjX2FnZ3JlZylbMV0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkaW0oQ2V0YWNlYV9vY2NfYWdncmVnW0NldGFjZWFfb2NjX2FnZ3JlZyRhY2NlcHRlZF9yYW5rID09InNwZWNpZXMiLF0pWzFdKSwKICAgICAgICAgICByZW1vdmVkID0gYyhkaW0oQ2V0YWNlYV9vY2MpWzFdLWRpbShDZXRhY2VhX29jY19hZ2dyZWcpWzFdLAogICAgICAgICAgICAgICAgICAgICAgIGRpbShDZXRhY2VhX29jY1tDZXRhY2VhX29jYyRhY2NlcHRlZF9yYW5rID09InNwZWNpZXMiLF0pWzFdLWRpbShDZXRhY2VhX29jY19hZ2dyZWdbQ2V0YWNlYV9vY2NfYWdncmVnJGFjY2VwdGVkX3JhbmsgPT0ic3BlY2llcyIsXSlbMV0pLAogICAgICAgICAgIHJvdy5uYW1lcyA9IGMoIk51bWJlciBvZiBvY2N1cnJlbmNlcyIsICJOdW1iZXIgb2Ygb2NjdXJyZW5jZXMgKHNwZWNpZXMgb25seSkiKSkKYGBgCgokXHRvJCBJbiB0aGF0IGNhc2UgdGhlIHN1Yi1zYW1wbGluZyBpcyBiaWcgZW5vdWdoIHRvIGhvcGUgY29ycmVjdGluZyBvdXIgYmlhcy4KCmBgYHtyIGZpZy53aWR0aD0xMCwgZmlnLmFzcD0wLjR9CiMgUmVjb3VudCB0aGUgbnVtYmVyIG9mIG9jY3VycmVuY2VzIHdpdGggdGhlIHNhbWUgYWNjZXB0ZWQgbmFtZSBhZnRlciB0aGUgYWdncmVnYXRpb24KQ2V0YWNlYV9vY2NfYWdncmVnJGFjY2VwdGVkX25hbWVfY291bnQgPC0gc2FwcGx5KENldGFjZWFfb2NjX2FnZ3JlZyRhY2NlcHRlZF9uYW1lLCBmdW5jdGlvbih4KXt0YWJsZShDZXRhY2VhX29jY19hZ2dyZWckYWNjZXB0ZWRfbmFtZSlbeF19KQoKb21lZ2EgPC0gMC4xCmFjY2VwdGVkX25hbWVfY291bnRfc3BlY2llcyA8LSBDZXRhY2VhX29jY1tDZXRhY2VhX29jYyRhY2NlcHRlZF9yYW5rPT0ic3BlY2llcyIsXSRhY2NlcHRlZF9uYW1lX2NvdW50CmRlbnMgPC0gc2FwcGx5KDE6bWF4KGFjY2VwdGVkX25hbWVfY291bnRfc3BlY2llcyksIGZ1bmN0aW9uKG4peyBleHBlY3RlZF9kaXN0cmlidXRpb24obiwgb21lZ2EsIENldGFjZWFfb2NjW0NldGFjZWFfb2NjJGFjY2VwdGVkX3Jhbms9PSJzcGVjaWVzIixdJHN0cmF0aWdyYXBoaWNfcmFuZ2VfZHVyYXRpb24pJHZhbHVlIH0pCmFjY2VwdGVkX25hbWVfY291bnRfY2F0ZWdvcmllcyA8LSB0YWJsZShhY2NlcHRlZF9uYW1lX2NvdW50X3NwZWNpZXMpL2FzLm51bWVyaWMobmFtZXModGFibGUoYWNjZXB0ZWRfbmFtZV9jb3VudF9zcGVjaWVzKSkpICAjIE51bWJlciBvZiBjYXRlZ29yaWVzIHdpdGggMSwgMiwgMywgLi4uIG9jY3VycmVuY2VzIG9mIHRoZSBzYW1lIHNwZWNpZXMKCiMgQ29tcGFyZSB0aGUgaW5pdGlhbCBvYnNlcnZlZCBkaXN0cmlidXRpb24gd2l0aCB0aGUgdGhlb3JldGljYWwgY3VydmUKZ2dwbG90KENldGFjZWFfb2NjW0NldGFjZWFfb2NjJGFjY2VwdGVkX3Jhbms9PSJzcGVjaWVzIixdLCAKICAgICAgIGFlcyh4PWFjY2VwdGVkX25hbWVfY291bnQsIAogICAgICAgICAgIHk9YWNjZXB0ZWRfbmFtZV9jb3VudF9jYXRlZ29yaWVzW2FzLmZhY3RvcihhY2NlcHRlZF9uYW1lX2NvdW50KV0sIAogICAgICAgICAgIGZpbGw9YWNjZXB0ZWRfcmFuaykpICsKICBnZW9tX3BvaW50KCkgKwogIAogIGFubm90YXRlKCJsaW5lIiwgeCA9IDE6bWF4KGFjY2VwdGVkX25hbWVfY291bnRfc3BlY2llcyksIHk9IGRlbnMKICAgICptYXgoKHRhYmxlKGFjY2VwdGVkX25hbWVfY291bnRfc3BlY2llcykvYXMubnVtZXJpYyhuYW1lcyh0YWJsZShhY2NlcHRlZF9uYW1lX2NvdW50X3NwZWNpZXMpKSkpW2FzLmZhY3RvcihhY2NlcHRlZF9uYW1lX2NvdW50X3NwZWNpZXMpXSkgL21heChkZW5zKSkrCiAgCiAgc2NhbGVfeF9jb250aW51b3VzKG5hbWUgPSAiTnVtYmVyIG9mIG9jY3VycmVuY2VzIGJ5IGFjY2VwdGVkIG5hbWUiKSArCiAgc2NhbGVfeV9jb250aW51b3VzKHRyYW5zID0gImxvZzEwIiwgbmFtZSA9ICJOdW1iZXIgb2YgY29ycmVzcG9uZGluZyBhY2NlcHRlZCBuYW1lcyAobG9nLXNjYWxlKSIpICsKICBzY2FsZV9maWxsX2Rpc2NyZXRlKG5hbWU9Ik9ic2VydmVkIGRpc3RyaWJ1dGlvbiIpICsKICB0aGVtZShwYW5lbC5ncmlkLm1ham9yLnggPSBlbGVtZW50X2JsYW5rKCksIAogICAgICAgIHBhbmVsLmdyaWQubWFqb3IueSA9IGVsZW1lbnRfYmxhbmsoKSkgKwogIGdndGl0bGUoIkNvbXBhcmlzb24gYmV0d2VlbiBleHBlY3RlZCBhbmQgb2JzZXJ2ZWQgZGlzdHJpYnV0aW9ucyBvZiBudW1iZXIgb2Ygb2NjdXJyZW5jZXMiKSArCiAgZmFjZXRfZ3JpZChhY2NlcHRlZF9yYW5rIH4gLiwgc2NhbGVzID0gImZyZWUiKQoKYWNjZXB0ZWRfbmFtZV9jb3VudF9zcGVjaWVzX2FnZ3JlZyA8LSBDZXRhY2VhX29jY19hZ2dyZWdbQ2V0YWNlYV9vY2NfYWdncmVnJGFjY2VwdGVkX3Jhbms9PSJzcGVjaWVzIixdJGFjY2VwdGVkX25hbWVfY291bnQKZGVuc19hZ2dyZWcgPC0gc2FwcGx5KDE6bWF4KGFjY2VwdGVkX25hbWVfY291bnRfc3BlY2llc19hZ2dyZWcpLCBmdW5jdGlvbihuKXsKICAgICBleHBlY3RlZF9kaXN0cmlidXRpb24obiwgb21lZ2EsIENldGFjZWFfb2NjX2FnZ3JlZ1tDZXRhY2VhX29jY19hZ2dyZWckYWNjZXB0ZWRfcmFuaz09InNwZWNpZXMiLF0kc3RyYXRpZ3JhcGhpY19yYW5nZV9kdXJhdGlvbikkdmFsdWUKICAgIH0pCmFjY2VwdGVkX25hbWVfY291bnRfY2F0ZWdvcmllc19hZ2dyZWcgPC0gdGFibGUoYWNjZXB0ZWRfbmFtZV9jb3VudF9zcGVjaWVzX2FnZ3JlZykvYXMubnVtZXJpYyhuYW1lcyh0YWJsZShhY2NlcHRlZF9uYW1lX2NvdW50X3NwZWNpZXNfYWdncmVnKSkpICAjIE51bWJlciBvZiBjYXRlZ29yaWVzIHdpdGggMSwgMiwgMywgLi4uIG9jY3VycmVuY2VzIG9mIHRoZSBzYW1lIHNwZWNpZXMKCiMgQ29tcGFyZSB0aGUgY29ycmVjdGVkIG9ic2VydmVkIGRpc3RyaWJ1dGlvbiB3aXRoIHRoZSB0aGVvcmV0aWNhbCBjdXJ2ZQpnZ3Bsb3QoQ2V0YWNlYV9vY2NfYWdncmVnW0NldGFjZWFfb2NjX2FnZ3JlZyRhY2NlcHRlZF9yYW5rPT0ic3BlY2llcyIsXSwgCiAgICAgICBhZXMoeD1hY2NlcHRlZF9uYW1lX2NvdW50LAogICAgICAgICAgIHk9YWNjZXB0ZWRfbmFtZV9jb3VudF9jYXRlZ29yaWVzX2FnZ3JlZ1thcy5mYWN0b3IoYWNjZXB0ZWRfbmFtZV9jb3VudCldLCAKICAgICAgICAgICBmaWxsPWFjY2VwdGVkX3JhbmspKSArCiAgZ2VvbV9wb2ludCgpICsKICAKICBhbm5vdGF0ZSgibGluZSIsIHggPSAxOm1heChhY2NlcHRlZF9uYW1lX2NvdW50X3NwZWNpZXNfYWdncmVnKSwgeT0gZGVuc19hZ2dyZWcKICAgICptYXgoKHRhYmxlKGFjY2VwdGVkX25hbWVfY291bnRfc3BlY2llc19hZ2dyZWcpL2FzLm51bWVyaWMobmFtZXModGFibGUoYWNjZXB0ZWRfbmFtZV9jb3VudF9zcGVjaWVzX2FnZ3JlZykpKSlbYXMuZmFjdG9yKGFjY2VwdGVkX25hbWVfY291bnRfc3BlY2llc19hZ2dyZWcpXSkgL21heChkZW5zX2FnZ3JlZykpICsKICAKICBzY2FsZV94X2NvbnRpbnVvdXMobmFtZSA9ICJOdW1iZXIgb2Ygb2NjdXJyZW5jZXMgYnkgYWNjZXB0ZWQgbmFtZSIpICsKICBzY2FsZV95X2NvbnRpbnVvdXModHJhbnMgPSAibG9nMTAiLCBuYW1lID0gIk51bWJlciBvZiBjb3JyZXNwb25kaW5nIGFjY2VwdGVkIG5hbWVzIChsb2ctc2NhbGUpIikgKwogIHNjYWxlX2ZpbGxfZGlzY3JldGUobmFtZT0iT2JzZXJ2ZWQgZGlzdHJpYnV0aW9uIikgKwogIHRoZW1lKHBhbmVsLmdyaWQubWFqb3IueCA9IGVsZW1lbnRfYmxhbmsoKSwgCiAgICAgICAgcGFuZWwuZ3JpZC5tYWpvci55ID0gZWxlbWVudF9ibGFuaygpKSArCiAgZ2d0aXRsZSgiQ29tcGFyaXNvbiBiZXR3ZWVuIGV4cGVjdGVkIGFuZCBvYnNlcnZlZCBkaXN0cmlidXRpb25zIG9mIG51bWJlciBvZiBvY2N1cnJlbmNlcywgYWZ0ZXIgYWdncmVnYXRpbmcgaW4gZm9ybWF0aW9ucyIpICsKICBmYWNldF9ncmlkKGFjY2VwdGVkX3JhbmsgfiAuLCBzY2FsZXMgPSAiZnJlZSIpCgphY2NlcHRlZF9uYW1lX2NvdW50X3NwZWNpZXNfYWdncmVnIDwtIENldGFjZWFfb2NjX2FnZ3JlZ1tDZXRhY2VhX29jY19hZ2dyZWckYWNjZXB0ZWRfcmFuaz09InNwZWNpZXMiLF0kYWNjZXB0ZWRfbmFtZV9jb3VudApkZW5zX2FnZ3JlZyA8LSBzYXBwbHkoMTptYXgoYWNjZXB0ZWRfbmFtZV9jb3VudF9zcGVjaWVzX2FnZ3JlZyksIGZ1bmN0aW9uKG4pewogICAgIGV4cGVjdGVkX2Rpc3RyaWJ1dGlvbihuLCBvbWVnYSwgQ2V0YWNlYV9vY2NfYWdncmVnW0NldGFjZWFfb2NjX2FnZ3JlZyRhY2NlcHRlZF9yYW5rPT0ic3BlY2llcyIsXSRzdHJhdGlncmFwaGljX3JhbmdlX2R1cmF0aW9uKSR2YWx1ZQogICAgfSkKYWNjZXB0ZWRfbmFtZV9jb3VudF9jYXRlZ29yaWVzX2FnZ3JlZyA8LSB0YWJsZShhY2NlcHRlZF9uYW1lX2NvdW50X3NwZWNpZXNfYWdncmVnKS9hcy5udW1lcmljKG5hbWVzKHRhYmxlKGFjY2VwdGVkX25hbWVfY291bnRfc3BlY2llc19hZ2dyZWcpKSkgICMgTnVtYmVyIG9mIGNhdGVnb3JpZXMgd2l0aCAxLCAyLCAzLCAuLi4gb2NjdXJyZW5jZXMgb2YgdGhlIHNhbWUgc3BlY2llcwpgYGAKCiRcdG8kIFRoZSBpbml0aWFsIGJpYXMgaXMgbW9zdGx5IGNvcnJlY3RlZC4KCmBgYHtyIGZpZy53aWR0aD0xMCwgZmlnLmFzcD0wLjUsIG1lc3NhZ2U9Rn0KY29uZGl0aW9ucyA8LSBDZXRhY2VhX29jYyRhY2NlcHRlZF9yYW5rID09InNwZWNpZXMiCgpwMSA8LSBnZ3Bsb3QoQ2V0YWNlYV9vY2NbY29uZGl0aW9ucyxdLCBhZXMoeD0tYWdlX3J1bmlmKSkgKwogIGdlb21faGlzdG9ncmFtKGJpbndpZHRoID0gMC41LCBhbHBoYT0wLjUsIGZpbGw9TkEsIGNvbD0icmVkIikgKwogIHhsaW0oLW1heChDZXRhY2VhX29jY1tjb25kaXRpb25zLF0kYWdlX3J1bmlmKS0xLCAxKSArCiAgeWxpbSgwLCA3MCkgKwogIHRoZW1lX3ZvaWQoKQoKcDIgPC0gZ2dwbG90KENldGFjZWFfb2NjX3NhbXBsZWQsIGFlcyh4PS1hZ2VfcnVuaWYpKSArCiAgZ2VvbV9oaXN0b2dyYW0oYmlud2lkdGggPSAwLjUsIGFscGhhPTAuNSwgZmlsbD0iYmx1ZSIpICsKICB4bGltKC1tYXgoQ2V0YWNlYV9vY2NbY29uZGl0aW9ucyxdJGFnZV9ydW5pZiktMSwgMSkgKwogIHlsaW0oMCwgNzApICsKICB0aGVtZV92b2lkKCkKCnAzIDwtIGdncGxvdChDZXRhY2VhX29jY19hZ2dyZWdbQ2V0YWNlYV9vY2NfYWdncmVnJGFjY2VwdGVkX3JhbmsgPT0ic3BlY2llcyIsXSwgYWVzKHg9LWFnZV9ydW5pZikpICsKICBnZW9tX2hpc3RvZ3JhbShiaW53aWR0aCA9IDAuNSwgYWxwaGE9MC41LCBmaWxsPSJncmVlbiIpICsKICB4bGltKC1tYXgoQ2V0YWNlYV9vY2NbY29uZGl0aW9ucyxdJGFnZV9ydW5pZiktMSwgMSkgKwogIHlsaW0oMCwgNzApICsKICB0aGVtZV92b2lkKCkKCiMgcDEgKyBhbm5vdGF0aW9uX2N1c3RvbShnZ3Bsb3RHcm9iKHAyKSkgKyBnZ3RpdGxlKCJJbml0aWFsIG9jY3VycmVuY2VzIGRpc3RyaWJ1dGlvbiAocmVkKSBhbmQgY29tcGFyaXNvbiBhZnRlciBzdWItc2FtcGxpbmcgKGJsdWUpIikKIyAKIyBwMSArIGFubm90YXRpb25fY3VzdG9tKGdncGxvdEdyb2IocDMpKSArIGdndGl0bGUoIkluaXRpYWwgb2NjdXJyZW5jZXMgZGlzdHJpYnV0aW9uIChyZWQpIGFuZCBjb21wYXJpc29uIGFmdGVyIGFnZ3JlZ2F0aW5nIGluIGZvcm1hdGlvbnMgKGdyZWVuKSIpCgpwMSArIGFubm90YXRpb25fY3VzdG9tKGdncGxvdEdyb2IocDIpKSArIGFubm90YXRpb25fY3VzdG9tKGdncGxvdEdyb2IocDMpKSArIGdndGl0bGUoIkluaXRpYWwgb2NjdXJyZW5jZXMgZGlzdHJpYnV0aW9uIChyZWQpIGFuZCBjb21wYXJpc29uIGFmdGVyIHN1Yi1zYW1wbGluZyAoYmx1ZSkgb3IgYWdncmVnYXRpbmcgaW4gZm9ybWF0aW9ucyAoZ3JlZW4pIikKYGBgCgokXHRvJCBDb21wYXJpbmcgd2l0aCB0aGUgaW5pdGlhbCBvY2N1cnJlbmNlcyBkaXN0cmlidXRpb24gYW5kIHdpdGggdGhlIGRpc3RyaWJ1dGlvbiBhZnRlciBvdXIgZmlyc3Qgc3ViLXNhbXBsaW5nIGl0IGFwcGVhcnMgdGhhdCBib3RoIG1ldGhvZHMgbGVhZCB0byB2ZXJ5IHNpbWlsYXIgZGlzdHJpYnV0aW9ucy4gVGhpcyBjb21mb3J0cyB1cyBhYm91dCB0aGUgcm9idXN0bmVzcyBvZiB0aG9zZSBhcHByb2FjaGVzLgoKSG93ZXZlciwgd2UgaGF2ZSB0byB0YWtlIGludG8gYWNjb3VudCB0aGUgb2NjdXJyZW5jZXMgdGhhdCBkbyBub3QgaGF2ZSBhbnkgaW5kaWNhdGVkIGdlb2xvZ2ljYWwgZm9ybWF0aW9uIHRvIHN1YnNhbXBsZSB0aGVtIHNlcGFyYXRlbHkuCgojIyBXcm9uZyB0cmFjazogQWdncmVnYXRlIG9jY3VycmVuY2VzIHdpdGhvdXQgZm9ybWF0aW9uIGJ5IGNvdW50cnkgKyBlYXJseSBpbnRlcnZhbAoKVG8gYXBwcm94aW1hdGUgZ2VvbG9naWNhbCBmb3JtYXRpb24gd2UgY2hvc2UgdG8gcHJvY2VlZCB0byB0aGUgYWdncmVnYXRpb24gYmFzZWQgb24gdGhlIGNvbWJpbmF0aW9uIG9mIHRoZSBjb3VudHJ5IGFuZCB0aGUgZWFybHkgc3RyYXRpZ3JhcGhpYyBpbnRlcnZhbC4KCmBgYHtyfQpDZXRhY2VhX29jY19hZ2dyZWcgPC0gYygpCgojIEJyb3dzZSBhbGwgY291bnRyaWVzCmNvdW50cmllcyA8LSBsZXZlbHMoZHJvcGxldmVscyhDZXRhY2VhX29jY1tDZXRhY2VhX29jYyRmb3JtYXRpb249PSIiLF0kY2MpKQpmb3IgKGNvdW50cnkgaW4gY291bnRyaWVzKXsKICBDZXRhY2VhX29jY19jYyA8LSBDZXRhY2VhX29jY1tDZXRhY2VhX29jYyRmb3JtYXRpb249PSIiICYgQ2V0YWNlYV9vY2MkY2M9PWNvdW50cnksXQogIAogICMgQnJvd3NlIGFsbCBlYXJseSBzdHJhdGlncmFwaGljIGludGVydmFscwogIGVhcmx5X2ludGVydmFscyA8LSBsZXZlbHMoZHJvcGxldmVscyhDZXRhY2VhX29jY19jYyRlYXJseV9pbnRlcnZhbCkpCiAgZm9yIChlaSBpbiBlYXJseV9pbnRlcnZhbHMpewogICAgQ2V0YWNlYV9vY2NfY2NfZWkgPC0gQ2V0YWNlYV9vY2NfY2NbQ2V0YWNlYV9vY2NfY2MkZWFybHlfaW50ZXJ2YWw9PWVpLF0KICAgIAogICAgIyBCcm93c2UgYWxsIGFjY2VwdGVkIG5hbWVzIGluIGVhY2ggY291bnRyeSAmIHNhbXBsZSBvbmx5IDEgb2NjdXJyZW5jZQogICAgdGF4YSA8LSBsZXZlbHMoZHJvcGxldmVscyhDZXRhY2VhX29jY19jY19laSRhY2NlcHRlZF9uYW1lKSkKICAgIGZvciAobmFtZSBpbiB0YXhhKXsKICAgICAgQ2V0YWNlYV9vY2NfYWdncmVnIDwtIHJiaW5kKENldGFjZWFfb2NjX2FnZ3JlZywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNhbXBsZV9uKENldGFjZWFfb2NjX2NjX2VpW0NldGFjZWFfb2NjX2NjX2VpJGFjY2VwdGVkX25hbWU9PW5hbWUsXSwgc2l6ZSA9IDEpKQogICAgfQogIH0KfQoKIyBCcm93c2UgYWxsIGZvcm1hdGlvbnMKZm9ybWF0aW9ucyA8LSBsZXZlbHMoZHJvcGxldmVscyhDZXRhY2VhX29jYyRmb3JtYXRpb24pKQpmb3IgKGZvcm0gaW4gZm9ybWF0aW9uc1std2hpY2goZm9ybWF0aW9ucz09IiIpXSl7CiAgQ2V0YWNlYV9vY2NfZm9ybSA8LSBDZXRhY2VhX29jY1tDZXRhY2VhX29jYyRmb3JtYXRpb249PWZvcm0sXQogIAogICMgQnJvd3NlIGFsbCBhY2NlcHRlZCBuYW1lcyBpbiBlYWNoIGZvcm1hdGlvbiAmIHNhbXBsZSBvbmx5IDEgb2NjdXJyZW5jZQogIHRheGEgPC0gbGV2ZWxzKGRyb3BsZXZlbHMoQ2V0YWNlYV9vY2NfZm9ybSRhY2NlcHRlZF9uYW1lKSkKICBmb3IgKG5hbWUgaW4gdGF4YSl7CiAgICBDZXRhY2VhX29jY19hZ2dyZWcgPC0gcmJpbmQoQ2V0YWNlYV9vY2NfYWdncmVnLCBzYW1wbGVfbihDZXRhY2VhX29jY19mb3JtW0NldGFjZWFfb2NjX2Zvcm0kYWNjZXB0ZWRfbmFtZT09bmFtZSxdLCBzaXplID0gMSkpCiAgfQp9CgpkYXRhLmZyYW1lKENldGFjZWFfb2NjID0gYyhkaW0oQ2V0YWNlYV9vY2MpWzFdLAogICAgICAgICAgICAgICAgICAgICAgICAgICBkaW0oQ2V0YWNlYV9vY2NbQ2V0YWNlYV9vY2MkYWNjZXB0ZWRfcmFuayA9PSJzcGVjaWVzIixdKVsxXSksCiAgICAgICAgICAgQ2V0YWNlYV9vY2NfYWdncmVnID0gYyhkaW0oQ2V0YWNlYV9vY2NfYWdncmVnKVsxXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRpbShDZXRhY2VhX29jY19hZ2dyZWdbQ2V0YWNlYV9vY2NfYWdncmVnJGFjY2VwdGVkX3JhbmsgPT0ic3BlY2llcyIsXSlbMV0pLAogICAgICAgICAgIHJlbW92ZWQgPSBjKGRpbShDZXRhY2VhX29jYylbMV0tZGltKENldGFjZWFfb2NjX2FnZ3JlZylbMV0sCiAgICAgICAgICAgICAgICAgICAgICAgZGltKENldGFjZWFfb2NjW0NldGFjZWFfb2NjJGFjY2VwdGVkX3JhbmsgPT0ic3BlY2llcyIsXSlbMV0tZGltKENldGFjZWFfb2NjX2FnZ3JlZ1tDZXRhY2VhX29jY19hZ2dyZWckYWNjZXB0ZWRfcmFuayA9PSJzcGVjaWVzIixdKVsxXSksCiAgICAgICAgICAgcm93Lm5hbWVzID0gYygiTnVtYmVyIG9mIG9jY3VycmVuY2VzIiwgIk51bWJlciBvZiBvY2N1cnJlbmNlcyAoc3BlY2llcyBvbmx5KSIpKQpgYGAKCk1vcmUgb2NjdXJyZW5jZXMgcmVtYWluIGFmdGVyIGFnZ3JlZ2F0aW5nIHdpdGggdGhpcyBuZXcgbWV0aG9kLiBMZXQncyBjb21wYXJlIGFnYWluIHdpdGggdGhlIHRoZW9yZXRpY2FsIGRpc3RyaWJ1dGlvbjoKCmBgYHtyIGZpZy53aWR0aD0xMCwgZmlnLmFzcD0wLjR9CiMgUmVjb3VudCB0aGUgbnVtYmVyIG9mIG9jY3VycmVuY2VzIHdpdGggdGhlIHNhbWUgYWNjZXB0ZWQgbmFtZSBhZnRlciB0aGUgYWdncmVnYXRpb24KQ2V0YWNlYV9vY2NfYWdncmVnJGFjY2VwdGVkX25hbWVfY291bnQgPC0gc2FwcGx5KENldGFjZWFfb2NjX2FnZ3JlZyRhY2NlcHRlZF9uYW1lLCBmdW5jdGlvbih4KXt0YWJsZShDZXRhY2VhX29jY19hZ2dyZWckYWNjZXB0ZWRfbmFtZSlbeF19KQoKb21lZ2EgPC0gMC4xNQphY2NlcHRlZF9uYW1lX2NvdW50X3NwZWNpZXMgPC0gQ2V0YWNlYV9vY2NbQ2V0YWNlYV9vY2MkYWNjZXB0ZWRfcmFuaz09InNwZWNpZXMiLF0kYWNjZXB0ZWRfbmFtZV9jb3VudApkZW5zIDwtIHNhcHBseSgxOm1heChhY2NlcHRlZF9uYW1lX2NvdW50X3NwZWNpZXMpLCBmdW5jdGlvbihuKXsgZXhwZWN0ZWRfZGlzdHJpYnV0aW9uKG4sIG9tZWdhLCBDZXRhY2VhX29jY1tDZXRhY2VhX29jYyRhY2NlcHRlZF9yYW5rPT0ic3BlY2llcyIsXSRzdHJhdGlncmFwaGljX3JhbmdlX2R1cmF0aW9uKSR2YWx1ZSB9KQphY2NlcHRlZF9uYW1lX2NvdW50X2NhdGVnb3JpZXMgPC0gdGFibGUoYWNjZXB0ZWRfbmFtZV9jb3VudF9zcGVjaWVzKS9hcy5udW1lcmljKG5hbWVzKHRhYmxlKGFjY2VwdGVkX25hbWVfY291bnRfc3BlY2llcykpKSAgIyBOdW1iZXIgb2YgY2F0ZWdvcmllcyB3aXRoIDEsIDIsIDMsIC4uLiBvY2N1cnJlbmNlcyBvZiB0aGUgc2FtZSBzcGVjaWVzCgojIENvbXBhcmUgdGhlIGluaXRpYWwgb2JzZXJ2ZWQgZGlzdHJpYnV0aW9uIHdpdGggdGhlIHRoZW9yZXRpY2FsIGN1cnZlCmdncGxvdChDZXRhY2VhX29jY1tDZXRhY2VhX29jYyRhY2NlcHRlZF9yYW5rPT0ic3BlY2llcyIsXSwgCiAgICAgICBhZXMoeD1hY2NlcHRlZF9uYW1lX2NvdW50LCAKICAgICAgICAgICB5PWFjY2VwdGVkX25hbWVfY291bnRfY2F0ZWdvcmllc1thcy5mYWN0b3IoYWNjZXB0ZWRfbmFtZV9jb3VudCldLCAKICAgICAgICAgICBmaWxsPWFjY2VwdGVkX3JhbmspKSArCiAgZ2VvbV9wb2ludCgpICsKICAKICBhbm5vdGF0ZSgibGluZSIsIHggPSAxOm1heChhY2NlcHRlZF9uYW1lX2NvdW50X3NwZWNpZXMpLCB5PSBkZW5zCiAgICAqbWF4KCh0YWJsZShhY2NlcHRlZF9uYW1lX2NvdW50X3NwZWNpZXMpL2FzLm51bWVyaWMobmFtZXModGFibGUoYWNjZXB0ZWRfbmFtZV9jb3VudF9zcGVjaWVzKSkpKVthcy5mYWN0b3IoYWNjZXB0ZWRfbmFtZV9jb3VudF9zcGVjaWVzKV0pIC9tYXgoZGVucykpKwogIAogIHNjYWxlX3hfY29udGludW91cyhuYW1lID0gIk51bWJlciBvZiBvY2N1cnJlbmNlcyBieSBhY2NlcHRlZCBuYW1lIikgKwogIHNjYWxlX3lfY29udGludW91cyh0cmFucyA9ICJsb2cxMCIsIG5hbWUgPSAiTnVtYmVyIG9mIGNvcnJlc3BvbmRpbmcgYWNjZXB0ZWQgbmFtZXMgKGxvZy1zY2FsZSkiKSArCiAgc2NhbGVfZmlsbF9kaXNjcmV0ZShuYW1lPSJPYnNlcnZlZCBkaXN0cmlidXRpb24iKSArCiAgdGhlbWUocGFuZWwuZ3JpZC5tYWpvci54ID0gZWxlbWVudF9ibGFuaygpLCAKICAgICAgICBwYW5lbC5ncmlkLm1ham9yLnkgPSBlbGVtZW50X2JsYW5rKCkpICsKICBnZ3RpdGxlKCJDb21wYXJpc29uIGJldHdlZW4gZXhwZWN0ZWQgYW5kIG9ic2VydmVkIGRpc3RyaWJ1dGlvbnMgb2YgbnVtYmVyIG9mIG9jY3VycmVuY2VzIikgKwogIGZhY2V0X2dyaWQoYWNjZXB0ZWRfcmFuayB+IC4sIHNjYWxlcyA9ICJmcmVlIikKCmFjY2VwdGVkX25hbWVfY291bnRfc3BlY2llc19hZ2dyZWcgPC0gQ2V0YWNlYV9vY2NfYWdncmVnW0NldGFjZWFfb2NjX2FnZ3JlZyRhY2NlcHRlZF9yYW5rPT0ic3BlY2llcyIsXSRhY2NlcHRlZF9uYW1lX2NvdW50CmRlbnNfYWdncmVnIDwtIHNhcHBseSgxOm1heChhY2NlcHRlZF9uYW1lX2NvdW50X3NwZWNpZXNfYWdncmVnKSwgZnVuY3Rpb24obil7CiAgICAgZXhwZWN0ZWRfZGlzdHJpYnV0aW9uKG4sIG9tZWdhLCBDZXRhY2VhX29jY19hZ2dyZWdbQ2V0YWNlYV9vY2NfYWdncmVnJGFjY2VwdGVkX3Jhbms9PSJzcGVjaWVzIixdJHN0cmF0aWdyYXBoaWNfcmFuZ2VfZHVyYXRpb24pJHZhbHVlCiAgICB9KQphY2NlcHRlZF9uYW1lX2NvdW50X2NhdGVnb3JpZXNfYWdncmVnIDwtIHRhYmxlKGFjY2VwdGVkX25hbWVfY291bnRfc3BlY2llc19hZ2dyZWcpL2FzLm51bWVyaWMobmFtZXModGFibGUoYWNjZXB0ZWRfbmFtZV9jb3VudF9zcGVjaWVzX2FnZ3JlZykpKSAgIyBOdW1iZXIgb2YgY2F0ZWdvcmllcyB3aXRoIDEsIDIsIDMsIC4uLiBvY2N1cnJlbmNlcyBvZiB0aGUgc2FtZSBzcGVjaWVzCgojIENvbXBhcmUgdGhlIGNvcnJlY3RlZCBvYnNlcnZlZCBkaXN0cmlidXRpb24gd2l0aCB0aGUgdGhlb3JldGljYWwgY3VydmUKZ2dwbG90KENldGFjZWFfb2NjX2FnZ3JlZ1tDZXRhY2VhX29jY19hZ2dyZWckYWNjZXB0ZWRfcmFuaz09InNwZWNpZXMiLF0sIAogICAgICAgYWVzKHg9YWNjZXB0ZWRfbmFtZV9jb3VudCwKICAgICAgICAgICB5PWFjY2VwdGVkX25hbWVfY291bnRfY2F0ZWdvcmllc19hZ2dyZWdbYXMuZmFjdG9yKGFjY2VwdGVkX25hbWVfY291bnQpXSwgCiAgICAgICAgICAgZmlsbD1hY2NlcHRlZF9yYW5rKSkgKwogIGdlb21fcG9pbnQoKSArCiAgCiAgYW5ub3RhdGUoImxpbmUiLCB4ID0gMTptYXgoYWNjZXB0ZWRfbmFtZV9jb3VudF9zcGVjaWVzX2FnZ3JlZyksIHk9IGRlbnNfYWdncmVnCiAgICAqbWF4KCh0YWJsZShhY2NlcHRlZF9uYW1lX2NvdW50X3NwZWNpZXNfYWdncmVnKS9hcy5udW1lcmljKG5hbWVzKHRhYmxlKGFjY2VwdGVkX25hbWVfY291bnRfc3BlY2llc19hZ2dyZWcpKSkpW2FzLmZhY3RvcihhY2NlcHRlZF9uYW1lX2NvdW50X3NwZWNpZXNfYWdncmVnKV0pIC9tYXgoZGVuc19hZ2dyZWcpKSArCiAgCiAgc2NhbGVfeF9jb250aW51b3VzKG5hbWUgPSAiTnVtYmVyIG9mIG9jY3VycmVuY2VzIGJ5IGFjY2VwdGVkIG5hbWUiKSArCiAgc2NhbGVfeV9jb250aW51b3VzKHRyYW5zID0gImxvZzEwIiwgbmFtZSA9ICJOdW1iZXIgb2YgY29ycmVzcG9uZGluZyBhY2NlcHRlZCBuYW1lcyAobG9nLXNjYWxlKSIpICsKICBzY2FsZV9maWxsX2Rpc2NyZXRlKG5hbWU9Ik9ic2VydmVkIGRpc3RyaWJ1dGlvbiIpICsKICB0aGVtZShwYW5lbC5ncmlkLm1ham9yLnggPSBlbGVtZW50X2JsYW5rKCksIAogICAgICAgIHBhbmVsLmdyaWQubWFqb3IueSA9IGVsZW1lbnRfYmxhbmsoKSkgKwogIGdndGl0bGUoIkNvbXBhcmlzb24gYmV0d2VlbiBleHBlY3RlZCBhbmQgb2JzZXJ2ZWQgZGlzdHJpYnV0aW9ucyBvZiBudW1iZXIgb2Ygb2NjdXJyZW5jZXMsIGFmdGVyIGFnZ3JlZ2F0aW5nIGluIGZvcm1hdGlvbnMiKSArCiAgZmFjZXRfZ3JpZChhY2NlcHRlZF9yYW5rIH4gLiwgc2NhbGVzID0gImZyZWUiKQoKYWNjZXB0ZWRfbmFtZV9jb3VudF9zcGVjaWVzX2FnZ3JlZyA8LSBDZXRhY2VhX29jY19hZ2dyZWdbQ2V0YWNlYV9vY2NfYWdncmVnJGFjY2VwdGVkX3Jhbms9PSJzcGVjaWVzIixdJGFjY2VwdGVkX25hbWVfY291bnQKZGVuc19hZ2dyZWcgPC0gc2FwcGx5KDE6bWF4KGFjY2VwdGVkX25hbWVfY291bnRfc3BlY2llc19hZ2dyZWcpLCBmdW5jdGlvbihuKXsKICAgICBleHBlY3RlZF9kaXN0cmlidXRpb24obiwgb21lZ2EsIENldGFjZWFfb2NjX2FnZ3JlZ1tDZXRhY2VhX29jY19hZ2dyZWckYWNjZXB0ZWRfcmFuaz09InNwZWNpZXMiLF0kc3RyYXRpZ3JhcGhpY19yYW5nZV9kdXJhdGlvbikkdmFsdWUKICAgIH0pCmFjY2VwdGVkX25hbWVfY291bnRfY2F0ZWdvcmllc19hZ2dyZWcgPC0gdGFibGUoYWNjZXB0ZWRfbmFtZV9jb3VudF9zcGVjaWVzX2FnZ3JlZykvYXMubnVtZXJpYyhuYW1lcyh0YWJsZShhY2NlcHRlZF9uYW1lX2NvdW50X3NwZWNpZXNfYWdncmVnKSkpICAjIE51bWJlciBvZiBjYXRlZ29yaWVzIHdpdGggMSwgMiwgMywgLi4uIG9jY3VycmVuY2VzIG9mIHRoZSBzYW1lIHNwZWNpZXMKYGBgCgokXHRvJCBUaGUgY29ycmVzcG9uZGVuY2UgaXMgc3RpbGwgZ29vZCwgZXhjZXB0IGZvciB0d28gdGF4YToKCmBgYHtyfQp0YWJsZShkcm9wbGV2ZWxzKENldGFjZWFfb2NjX2FnZ3JlZ1tDZXRhY2VhX29jY19hZ2dyZWckYWNjZXB0ZWRfcmFuaz09InNwZWNpZXMiLF1bYWNjZXB0ZWRfbmFtZV9jb3VudF9zcGVjaWVzX2FnZ3JlZz4xMCxdJGFjY2VwdGVkX25hbWUpKQpgYGAKCmBgYHtyLCB3YXJuaW5nPUZBTFNFfQpDZXRhY2VhX29jY19hZ2dyZWckYWdlX3VuY2VydGFpbnR5IDwtIENldGFjZWFfb2NjX2FnZ3JlZyRtYXhfbWEtQ2V0YWNlYV9vY2NfYWdncmVnJG1pbl9tYQpDZXRhY2VhX29jY19hZ2dyZWckbWluX21pbl9tYSA8LSBhcHBseShDZXRhY2VhX29jY19hZ2dyZWcsIDEsIGZ1bmN0aW9uKFgpe21pbihDZXRhY2VhX29jY19hZ2dyZWdbQ2V0YWNlYV9vY2NfYWdncmVnJGFnZV91bmNlcnRhaW50eTwxMCAmIENldGFjZWFfb2NjX2FnZ3JlZyRhY2NlcHRlZF9uYW1lPT1YWyJhY2NlcHRlZF9uYW1lIl0sXSRtaW5fbWEpfSkKQ2V0YWNlYV9vY2NfYWdncmVnJG1heF9tYXhfbWEgPC0gYXBwbHkoQ2V0YWNlYV9vY2NfYWdncmVnLCAxLCBmdW5jdGlvbihYKXttYXgoQ2V0YWNlYV9vY2NfYWdncmVnW0NldGFjZWFfb2NjX2FnZ3JlZyRhZ2VfdW5jZXJ0YWludHk8MTAgJiBDZXRhY2VhX29jY19hZ2dyZWckYWNjZXB0ZWRfbmFtZT09WFsiYWNjZXB0ZWRfbmFtZSJdLF0kbWF4X21hKX0pCkNldGFjZWFfb2NjX2FnZ3JlZyRzdHJhdGlncmFwaGljX3JhbmdlX21pZHBvaW50IDwtIChDZXRhY2VhX29jY19hZ2dyZWckbWluX21pbl9tYSArIENldGFjZWFfb2NjX2FnZ3JlZyRtYXhfbWF4X21hKS8yCkNldGFjZWFfb2NjX2FnZ3JlZyRzdHJhdGlncmFwaGljX3JhbmdlX2R1cmF0aW9uIDwtIENldGFjZWFfb2NjX2FnZ3JlZyRtYXhfbWF4X21hLUNldGFjZWFfb2NjX2FnZ3JlZyRtaW5fbWluX21hCkNldGFjZWFfb2NjX2FnZ3JlZyRhY2NlcHRlZF9uYW1lX2NvdW50IDwtIHNhcHBseShDZXRhY2VhX29jY19hZ2dyZWckYWNjZXB0ZWRfbmFtZSwgZnVuY3Rpb24oeCl7dGFibGUoQ2V0YWNlYV9vY2NfYWdncmVnJGFjY2VwdGVkX25hbWUpW3hdfSkKQ2V0YWNlYV9vY2NfYWdncmVnJG9jY3VycmVuY2VfY29tYmluZWRfZGVuc2l0eSA8LSBDZXRhY2VhX29jY19hZ2dyZWckYWNjZXB0ZWRfbmFtZV9jb3VudC9DZXRhY2VhX29jY19hZ2dyZWckc3RyYXRpZ3JhcGhpY19yYW5nZV9kdXJhdGlvbgpgYGAKCmBgYHtyIGZpZy5hc3A9MC41LCBmaWcud2lkdGg9MTAsIG1lc3NhZ2U9RkFMU0V9CmJyZWFrcyA8LSBjKDAuMTI1LDAuMjUsMC41LDEsMiw0LDgsMTYpCgpwX2JlZm9yZSA8LSBnZ3Bsb3QoQ2V0YWNlYV9vY2NbQ2V0YWNlYV9vY2MkYWNjZXB0ZWRfcmFuayA9PSJzcGVjaWVzIiAmIENldGFjZWFfb2NjJGFnZV91bmNlcnRhaW50eTwxMCxdLCBhZXMoeD0tbWF4X21hLCB5PWFjY2VwdGVkX25hbWUpKSArCiAgZ2VvbV9zZWdtZW50KGFlcyh4ID0gLW1heF9tYXhfbWEsIHkgPSByZW9yZGVyKGFjY2VwdGVkX25hbWUsIC1zdHJhdGlncmFwaGljX3JhbmdlX21pZHBvaW50KSwgeGVuZCA9IC1taW5fbWluX21hLCB5ZW5kPXJlb3JkZXIoYWNjZXB0ZWRfbmFtZSwgLXN0cmF0aWdyYXBoaWNfcmFuZ2VfbWlkcG9pbnQpLCBjb2xvcj1vY2N1cnJlbmNlX2NvbWJpbmVkX2RlbnNpdHkpLCBhcnJvdz1hcnJvdyhlbmRzID0gImJvdGgiLCBhbmdsZT05MCwgbGVuZ3RoID0gdW5pdCgxLCAibW0iKSksIGFscGhhPTAuNSkgKwogIGdlb21fcG9pbnQoYWVzKHg9LWFnZV9ydW5pZiksIGNvbD0icmVkIiwgY2V4PTAuNSwgYWxwaGE9MC41KSArCiAgc2NhbGVfeF9jb250aW51b3VzKG5hbWUgPSAiVGltZSAoTXkpIikgKwogIHNjYWxlX3lfZGlzY3JldGUobmFtZSA9ICJTcGVjaWVzIikgKwogIGxhYnMoY29sb3VyPSJPY2N1cnJlbmNlXG5kZW5zaXR5IikgKwogIHRoZW1lKGF4aXMudGV4dC55PWVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLnRpY2tzLnk9ZWxlbWVudF9ibGFuaygpLAogICAgICAgIHBhbmVsLmdyaWQubWFqb3IueSA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBwbG90LmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbCA9ICJ0cmFuc3BhcmVudCIsIGNvbG9yID0gTkEpLAogICAgICAgIGxlZ2VuZC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGwgPSAidHJhbnNwYXJlbnQiLCBjb2xvciA9IE5BKSwKICAgICAgICBsZWdlbmQuYm94LmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbCA9ICJ0cmFuc3BhcmVudCIsIGNvbG9yID0gTkEpKSArCiAgc2NhbGVfY29sb3JfZ3JhZGllbnRuKGNvbG91cnMgPSBjKCJkYXJrYmx1ZSIsICJmb3Jlc3RncmVlbiIsICJibGFjayIpLCB0cmFucz0ibG9nIiwgYnJlYWtzPWJyZWFrcywgbGFiZWxzPWJyZWFrcykgKyAKICBnZ3RpdGxlKHBhc3RlKCJEaXN0cmlidXRpb25zIG9mIHNwZWNpZXMgZm9zc2lsIGFnZSB1bmNlcnRhaW50aWVzLCBiZWZvcmUgc3Vic2FtcGxpbmcgKG4gPSAiLCBkaW0oQ2V0YWNlYV9vY2NbQ2V0YWNlYV9vY2MkYWNjZXB0ZWRfcmFuayA9PSJzcGVjaWVzIiAmIENldGFjZWFfb2NjJGFnZV91bmNlcnRhaW50eTwxMCxdKVsxXSwgIikiLCBzZXA9IiIpKQpwX2JlZm9yZQoKZ2dzYXZlKCIuLi9JbWFnZXMvUmFuZ2VfZGlzdHJpYnV0aW9uc19iZWZvcmVfYWdncmVnYXRpbmcuc3ZnIiwgcGxvdCA9IHBfYmVmb3JlLCBkZXZpY2UgPSAic3ZnIiwgYmcgPSAidHJhbnNwYXJlbnQiKQoKcF9hZnRlciA8LSBnZ3Bsb3QoQ2V0YWNlYV9vY2NfYWdncmVnW0NldGFjZWFfb2NjX2FnZ3JlZyRhY2NlcHRlZF9yYW5rID09InNwZWNpZXMiICYgQ2V0YWNlYV9vY2NfYWdncmVnJGFnZV91bmNlcnRhaW50eTwxMCxdLCBhZXMoeD0tbWF4X21hLCB5PWFjY2VwdGVkX25hbWUpKSArCiAgZ2VvbV9zZWdtZW50KGFlcyh4ID0gLW1heF9tYXhfbWEsIHkgPSByZW9yZGVyKGFjY2VwdGVkX25hbWUsIC1zdHJhdGlncmFwaGljX3JhbmdlX21pZHBvaW50KSwgeGVuZCA9IC1taW5fbWluX21hLCB5ZW5kPXJlb3JkZXIoYWNjZXB0ZWRfbmFtZSwgLXN0cmF0aWdyYXBoaWNfcmFuZ2VfbWlkcG9pbnQpLCBjb2xvcj1vY2N1cnJlbmNlX2NvbWJpbmVkX2RlbnNpdHkpLCBhcnJvdz1hcnJvdyhlbmRzID0gImJvdGgiLCBhbmdsZT05MCwgbGVuZ3RoID0gdW5pdCgxLCAibW0iKSksIGFscGhhPTAuNSkgKwogIGdlb21fcG9pbnQoYWVzKHg9LWFnZV9ydW5pZiksIGNvbD0icmVkIiwgY2V4PTAuNSwgYWxwaGE9MC41KSArCiAgc2NhbGVfeF9jb250aW51b3VzKG5hbWUgPSAiVGltZSAoTXkpIikgKwogIHNjYWxlX3lfZGlzY3JldGUobmFtZSA9ICJTcGVjaWVzIikgKwogIGxhYnMoY29sb3VyPSJPY2N1cnJlbmNlXG5kZW5zaXR5IikgKwogIHRoZW1lKGF4aXMudGV4dC55PWVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLnRpY2tzLnk9ZWxlbWVudF9ibGFuaygpLAogICAgICAgIHBhbmVsLmdyaWQubWFqb3IueSA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBwbG90LmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbCA9ICJ0cmFuc3BhcmVudCIsIGNvbG9yID0gTkEpLAogICAgICAgIGxlZ2VuZC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGwgPSAidHJhbnNwYXJlbnQiLCBjb2xvciA9IE5BKSwKICAgICAgICBsZWdlbmQuYm94LmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbCA9ICJ0cmFuc3BhcmVudCIsIGNvbG9yID0gTkEpKSArCiAgc2NhbGVfY29sb3JfZ3JhZGllbnRuKGNvbG91cnMgPSBjKCJkYXJrYmx1ZSIsICJmb3Jlc3RncmVlbiIsICJibGFjayIpLCB0cmFucz0ibG9nIiwgYnJlYWtzPWJyZWFrcywgbGFiZWxzPWJyZWFrcykgKyAKICBnZ3RpdGxlKHBhc3RlKCJEaXN0cmlidXRpb25zIG9mIHNwZWNpZXMgZm9zc2lsIGFnZSB1bmNlcnRhaW50aWVzLCBhZnRlciBzdWJzYW1wbGluZyBieSBhZ2dyZWdhdGlvbiAobiA9ICIsIGRpbShDZXRhY2VhX29jY19zYW1wbGVkKVsxXSwgIikiLCBzZXA9IiIpKQpwX2FmdGVyCgpnZ3NhdmUoIi4uL0ltYWdlcy9SYW5nZV9kaXN0cmlidXRpb25zX2FmdGVyX2FnZ3JlZ2F0aW5nLnN2ZyIsIHBsb3QgPSBwX2FmdGVyLCBkZXZpY2UgPSAic3ZnIiwgYmcgPSAidHJhbnNwYXJlbnQiKQpgYGAKCmBgYHtyIGZpZy53aWR0aD0xMCwgZmlnLmFzcD0wLjV9CmNvbmRpdGlvbnMgPC0gQ2V0YWNlYV9vY2MkYWNjZXB0ZWRfcmFuayA9PSJzcGVjaWVzIgoKcDEgPC0gZ2dwbG90KENldGFjZWFfb2NjW2NvbmRpdGlvbnMsXSwgYWVzKHg9LWFnZV9ydW5pZikpICsKICBnZW9tX2hpc3RvZ3JhbShiaW53aWR0aCA9IDAuNSwgYWxwaGE9MC41LCBmaWxsPU5BLCBjb2w9InJlZCIpICsKICB4bGltKC1tYXgoQ2V0YWNlYV9vY2NbY29uZGl0aW9ucyxdJGFnZV9ydW5pZiktMSwgMSkgKwogIHlsaW0oMCwgNzApICsKICB0aGVtZV92b2lkKCkKCnAyIDwtIGdncGxvdChDZXRhY2VhX29jY19zYW1wbGVkLCBhZXMoeD0tYWdlX3J1bmlmKSkgKwogIGdlb21faGlzdG9ncmFtKGJpbndpZHRoID0gMC41LCBhbHBoYT0wLjUsIGZpbGw9ImJsdWUiKSArCiAgeGxpbSgtbWF4KENldGFjZWFfb2NjW2NvbmRpdGlvbnMsXSRhZ2VfcnVuaWYpLTEsIDEpICsKICB5bGltKDAsIDcwKSArCiAgdGhlbWVfdm9pZCgpCgpwMyA8LSBnZ3Bsb3QoQ2V0YWNlYV9vY2NfYWdncmVnW0NldGFjZWFfb2NjX2FnZ3JlZyRhY2NlcHRlZF9yYW5rID09InNwZWNpZXMiLF0sIGFlcyh4PS1hZ2VfcnVuaWYpKSArCiAgZ2VvbV9oaXN0b2dyYW0oYmlud2lkdGggPSAwLjUsIGFscGhhPTAuNSwgZmlsbD0iZ3JlZW4iKSArCiAgeGxpbSgtbWF4KENldGFjZWFfb2NjW2NvbmRpdGlvbnMsXSRhZ2VfcnVuaWYpLTEsIDEpICsKICB5bGltKDAsIDcwKSArCiAgdGhlbWVfdm9pZCgpCgojIHAxICsgYW5ub3RhdGlvbl9jdXN0b20oZ2dwbG90R3JvYihwMikpICsgZ2d0aXRsZSgiSW5pdGlhbCBvY2N1cnJlbmNlcyBkaXN0cmlidXRpb24gKHJlZCkgYW5kIGNvbXBhcmlzb24gYWZ0ZXIgc3ViLXNhbXBsaW5nIChibHVlKSIpCiMgCiMgcDEgKyBhbm5vdGF0aW9uX2N1c3RvbShnZ3Bsb3RHcm9iKHAzKSkgKyBnZ3RpdGxlKCJJbml0aWFsIG9jY3VycmVuY2VzIGRpc3RyaWJ1dGlvbiAocmVkKSBhbmQgY29tcGFyaXNvbiBhZnRlciBhZ2dyZWdhdGluZyBpbiBmb3JtYXRpb25zIChncmVlbikiKQoKcF9hbGwgPC0gcDEgKyBhbm5vdGF0aW9uX2N1c3RvbShnZ3Bsb3RHcm9iKHAyKSkgKyBhbm5vdGF0aW9uX2N1c3RvbShnZ3Bsb3RHcm9iKHAzKSkgKyBnZ3RpdGxlKCJJbml0aWFsIG9jY3VycmVuY2VzIGRpc3RyaWJ1dGlvbiAocmVkKSBhbmQgY29tcGFyaXNvbiBhZnRlciBzdWItc2FtcGxpbmcgKGJsdWUpIG9yIGFnZ3JlZ2F0aW5nIGluIGZvcm1hdGlvbnMgKGdyZWVuKSIpICsgdGhlbWUocGxvdC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGwgPSAidHJhbnNwYXJlbnQiLCBjb2xvciA9IE5BKSkKcF9hbGwKCmdnc2F2ZSgiLi4vSW1hZ2VzL09jY3VycmVuY2VfZGlzdHJpYnV0aW9uc19jb21wYXJpc29uLnN2ZyIsIHBsb3QgPSBwX2FsbCwgZGV2aWNlID0gInN2ZyIsIGJnID0gInRyYW5zcGFyZW50IikKYGBgCgokXHRvJCBDb21wYXJpbmcgd2l0aCB0aGUgaW5pdGlhbCBvY2N1cnJlbmNlcyBkaXN0cmlidXRpb24gYW5kIHdpdGggdGhlIGRpc3RyaWJ1dGlvbiBhZnRlciBvdXIgZmlyc3Qgc3ViLXNhbXBsaW5nIGl0IGFwcGVhcnMgdGhhdCBib3RoIG1ldGhvZHMgbGVhZCB0byB2ZXJ5IHNpbWlsYXIgZGlzdHJpYnV0aW9ucy4gVGhpcyBjb21mb3J0cyB1cyBhYm91dCB0aGUgcm9idXN0bmVzcyBvZiB0aG9zZSBhcHByb2FjaGVzLgoKUmVwbGFjaW5nIGNvdW50cmllcyBieSBnZW9sb2dpY2FsIHBsYXRlcyBzZWVtcyB0byBtYWtlIG1vcmUgc2VucyBmcm9tIGEgcGFsYWVvbnRvbG9naWNhbCBwZXJzcGVjdGl2ZSwgc28gbGV0J3MgdHJ5IGl0LgoKIyMgQWdncmVnYXRlIG9jY3VycmVuY2VzIHdpdGhvdXQgZm9ybWF0aW9uIGJ5IGdlb3BsYXRlICsgZWFybHkgaW50ZXJ2YWwKCmBgYHtyfQpDZXRhY2VhX29jY19hZ2dyZWcgPC0gYygpCgojIEJyb3dzZSBhbGwgZ2VvcGxhdGVzCmdlb3BsYXRlcyA8LSBsZXZlbHMoZHJvcGxldmVscyhDZXRhY2VhX29jY1tDZXRhY2VhX29jYyRmb3JtYXRpb249PSIiLF0kZ2VvcGxhdGUpKQpmb3IgKGdwIGluIGdlb3BsYXRlcyl7CiAgQ2V0YWNlYV9vY2NfZ3AgPC0gQ2V0YWNlYV9vY2NbQ2V0YWNlYV9vY2MkZm9ybWF0aW9uPT0iIiAmIENldGFjZWFfb2NjJGdlb3BsYXRlPT1ncCxdCiAgCiAgIyBCcm93c2UgYWxsIGVhcmx5IHN0cmF0aWdyYXBoaWMgaW50ZXJ2YWxzCiAgZWFybHlfaW50ZXJ2YWxzIDwtIGxldmVscyhkcm9wbGV2ZWxzKENldGFjZWFfb2NjX2dwJGVhcmx5X2ludGVydmFsKSkKICBmb3IgKGVpIGluIGVhcmx5X2ludGVydmFscyl7CiAgICBDZXRhY2VhX29jY19ncF9laSA8LSBDZXRhY2VhX29jY19ncFtDZXRhY2VhX29jY19ncCRlYXJseV9pbnRlcnZhbD09ZWksXQogICAgCiAgICAjIEJyb3dzZSBhbGwgYWNjZXB0ZWQgbmFtZXMgJiBzYW1wbGUgb25seSAxIG9jY3VycmVuY2UKICAgIHRheGEgPC0gbGV2ZWxzKGRyb3BsZXZlbHMoQ2V0YWNlYV9vY2NfZ3BfZWkkYWNjZXB0ZWRfbmFtZSkpCiAgICBmb3IgKG5hbWUgaW4gdGF4YSl7CiAgICAgIENldGFjZWFfb2NjX2FnZ3JlZyA8LSByYmluZChDZXRhY2VhX29jY19hZ2dyZWcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzYW1wbGVfbihDZXRhY2VhX29jY19ncF9laVtDZXRhY2VhX29jY19ncF9laSRhY2NlcHRlZF9uYW1lPT1uYW1lLF0sIHNpemUgPSAxKSkKICAgIH0KICB9Cn0KCiMgQnJvd3NlIGFsbCBmb3JtYXRpb25zCmZvcm1hdGlvbnMgPC0gbGV2ZWxzKGRyb3BsZXZlbHMoQ2V0YWNlYV9vY2MkZm9ybWF0aW9uKSkKZm9yIChmb3JtIGluIGZvcm1hdGlvbnNbLXdoaWNoKGZvcm1hdGlvbnM9PSIiKV0pewogIENldGFjZWFfb2NjX2Zvcm0gPC0gQ2V0YWNlYV9vY2NbQ2V0YWNlYV9vY2MkZm9ybWF0aW9uPT1mb3JtLF0KICAKICAjIEJyb3dzZSBhbGwgYWNjZXB0ZWQgbmFtZXMgaW4gZWFjaCBmb3JtYXRpb24gJiBzYW1wbGUgb25seSAxIG9jY3VycmVuY2UKICB0YXhhIDwtIGxldmVscyhkcm9wbGV2ZWxzKENldGFjZWFfb2NjX2Zvcm0kYWNjZXB0ZWRfbmFtZSkpCiAgZm9yIChuYW1lIGluIHRheGEpewogICAgQ2V0YWNlYV9vY2NfYWdncmVnIDwtIHJiaW5kKENldGFjZWFfb2NjX2FnZ3JlZywgc2FtcGxlX24oQ2V0YWNlYV9vY2NfZm9ybVtDZXRhY2VhX29jY19mb3JtJGFjY2VwdGVkX25hbWU9PW5hbWUsXSwgc2l6ZSA9IDEpKQogIH0KfQoKZGF0YS5mcmFtZShDZXRhY2VhX29jYyA9IGMoZGltKENldGFjZWFfb2NjKVsxXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgZGltKENldGFjZWFfb2NjW0NldGFjZWFfb2NjJGFjY2VwdGVkX3JhbmsgPT0ic3BlY2llcyIsXSlbMV0pLAogICAgICAgICAgIENldGFjZWFfb2NjX2FnZ3JlZyA9IGMoZGltKENldGFjZWFfb2NjX2FnZ3JlZylbMV0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkaW0oQ2V0YWNlYV9vY2NfYWdncmVnW0NldGFjZWFfb2NjX2FnZ3JlZyRhY2NlcHRlZF9yYW5rID09InNwZWNpZXMiLF0pWzFdKSwKICAgICAgICAgICByZW1vdmVkID0gYyhkaW0oQ2V0YWNlYV9vY2MpWzFdLWRpbShDZXRhY2VhX29jY19hZ2dyZWcpWzFdLAogICAgICAgICAgICAgICAgICAgICAgIGRpbShDZXRhY2VhX29jY1tDZXRhY2VhX29jYyRhY2NlcHRlZF9yYW5rID09InNwZWNpZXMiLF0pWzFdLWRpbShDZXRhY2VhX29jY19hZ2dyZWdbQ2V0YWNlYV9vY2NfYWdncmVnJGFjY2VwdGVkX3JhbmsgPT0ic3BlY2llcyIsXSlbMV0pLAogICAgICAgICAgIHJvdy5uYW1lcyA9IGMoIk51bWJlciBvZiBvY2N1cnJlbmNlcyIsICJOdW1iZXIgb2Ygb2NjdXJyZW5jZXMgKHNwZWNpZXMgb25seSkiKSkKYGBgCgpNb3JlIG9jY3VycmVuY2VzIHJlbWFpbiBhZnRlciBhZ2dyZWdhdGluZyB3aXRoIHRoaXMgbmV3IG1ldGhvZC4gTGV0J3MgY29tcGFyZSBhZ2FpbiB3aXRoIHRoZSB0aGVvcmV0aWNhbCBkaXN0cmlidXRpb246CgpgYGB7ciBmaWcud2lkdGg9MTAsIGZpZy5hc3A9MC40fQojIFJlY291bnQgdGhlIG51bWJlciBvZiBvY2N1cnJlbmNlcyB3aXRoIHRoZSBzYW1lIGFjY2VwdGVkIG5hbWUgYWZ0ZXIgdGhlIGFnZ3JlZ2F0aW9uCkNldGFjZWFfb2NjX2FnZ3JlZyRhY2NlcHRlZF9uYW1lX2NvdW50IDwtIHNhcHBseShDZXRhY2VhX29jY19hZ2dyZWckYWNjZXB0ZWRfbmFtZSwgZnVuY3Rpb24oeCl7dGFibGUoQ2V0YWNlYV9vY2NfYWdncmVnJGFjY2VwdGVkX25hbWUpW3hdfSkKCm9tZWdhIDwtIDAuMTUKYWNjZXB0ZWRfbmFtZV9jb3VudF9zcGVjaWVzIDwtIENldGFjZWFfb2NjW0NldGFjZWFfb2NjJGFjY2VwdGVkX3Jhbms9PSJzcGVjaWVzIixdJGFjY2VwdGVkX25hbWVfY291bnQKZGVucyA8LSBzYXBwbHkoMTptYXgoYWNjZXB0ZWRfbmFtZV9jb3VudF9zcGVjaWVzKSwgZnVuY3Rpb24obil7IGV4cGVjdGVkX2Rpc3RyaWJ1dGlvbihuLCBvbWVnYSwgQ2V0YWNlYV9vY2NbQ2V0YWNlYV9vY2MkYWNjZXB0ZWRfcmFuaz09InNwZWNpZXMiLF0kc3RyYXRpZ3JhcGhpY19yYW5nZV9kdXJhdGlvbikkdmFsdWUgfSkKYWNjZXB0ZWRfbmFtZV9jb3VudF9jYXRlZ29yaWVzIDwtIHRhYmxlKGFjY2VwdGVkX25hbWVfY291bnRfc3BlY2llcykvYXMubnVtZXJpYyhuYW1lcyh0YWJsZShhY2NlcHRlZF9uYW1lX2NvdW50X3NwZWNpZXMpKSkgICMgTnVtYmVyIG9mIGNhdGVnb3JpZXMgd2l0aCAxLCAyLCAzLCAuLi4gb2NjdXJyZW5jZXMgb2YgdGhlIHNhbWUgc3BlY2llcwoKIyBDb21wYXJlIHRoZSBpbml0aWFsIG9ic2VydmVkIGRpc3RyaWJ1dGlvbiB3aXRoIHRoZSB0aGVvcmV0aWNhbCBjdXJ2ZQpnZ3Bsb3QoQ2V0YWNlYV9vY2NbQ2V0YWNlYV9vY2MkYWNjZXB0ZWRfcmFuaz09InNwZWNpZXMiLF0sIAogICAgICAgYWVzKHg9YWNjZXB0ZWRfbmFtZV9jb3VudCwgCiAgICAgICAgICAgeT1hY2NlcHRlZF9uYW1lX2NvdW50X2NhdGVnb3JpZXNbYXMuZmFjdG9yKGFjY2VwdGVkX25hbWVfY291bnQpXSwgCiAgICAgICAgICAgZmlsbD1hY2NlcHRlZF9yYW5rKSkgKwogIGdlb21fcG9pbnQoKSArCiAgCiAgYW5ub3RhdGUoImxpbmUiLCB4ID0gMTptYXgoYWNjZXB0ZWRfbmFtZV9jb3VudF9zcGVjaWVzKSwgeT0gZGVucwogICAgKm1heCgodGFibGUoYWNjZXB0ZWRfbmFtZV9jb3VudF9zcGVjaWVzKS9hcy5udW1lcmljKG5hbWVzKHRhYmxlKGFjY2VwdGVkX25hbWVfY291bnRfc3BlY2llcykpKSlbYXMuZmFjdG9yKGFjY2VwdGVkX25hbWVfY291bnRfc3BlY2llcyldKSAvbWF4KGRlbnMpKSsKICAKICBzY2FsZV94X2NvbnRpbnVvdXMobmFtZSA9ICJOdW1iZXIgb2Ygb2NjdXJyZW5jZXMgYnkgYWNjZXB0ZWQgbmFtZSIpICsKICBzY2FsZV95X2NvbnRpbnVvdXModHJhbnMgPSAibG9nMTAiLCBuYW1lID0gIk51bWJlciBvZiBjb3JyZXNwb25kaW5nIGFjY2VwdGVkIG5hbWVzIChsb2ctc2NhbGUpIikgKwogIHNjYWxlX2ZpbGxfZGlzY3JldGUobmFtZT0iT2JzZXJ2ZWQgZGlzdHJpYnV0aW9uIikgKwogIHRoZW1lKHBhbmVsLmdyaWQubWFqb3IueCA9IGVsZW1lbnRfYmxhbmsoKSwgCiAgICAgICAgcGFuZWwuZ3JpZC5tYWpvci55ID0gZWxlbWVudF9ibGFuaygpKSArCiAgZ2d0aXRsZSgiQ29tcGFyaXNvbiBiZXR3ZWVuIGV4cGVjdGVkIGFuZCBvYnNlcnZlZCBkaXN0cmlidXRpb25zIG9mIG51bWJlciBvZiBvY2N1cnJlbmNlcyIpICsKICBmYWNldF9ncmlkKGFjY2VwdGVkX3JhbmsgfiAuLCBzY2FsZXMgPSAiZnJlZSIpCgphY2NlcHRlZF9uYW1lX2NvdW50X3NwZWNpZXNfYWdncmVnIDwtIENldGFjZWFfb2NjX2FnZ3JlZ1tDZXRhY2VhX29jY19hZ2dyZWckYWNjZXB0ZWRfcmFuaz09InNwZWNpZXMiLF0kYWNjZXB0ZWRfbmFtZV9jb3VudApkZW5zX2FnZ3JlZyA8LSBzYXBwbHkoMTptYXgoYWNjZXB0ZWRfbmFtZV9jb3VudF9zcGVjaWVzX2FnZ3JlZyksIGZ1bmN0aW9uKG4pewogICAgIGV4cGVjdGVkX2Rpc3RyaWJ1dGlvbihuLCBvbWVnYSwgQ2V0YWNlYV9vY2NfYWdncmVnW0NldGFjZWFfb2NjX2FnZ3JlZyRhY2NlcHRlZF9yYW5rPT0ic3BlY2llcyIsXSRzdHJhdGlncmFwaGljX3JhbmdlX2R1cmF0aW9uKSR2YWx1ZQogICAgfSkKYWNjZXB0ZWRfbmFtZV9jb3VudF9jYXRlZ29yaWVzX2FnZ3JlZyA8LSB0YWJsZShhY2NlcHRlZF9uYW1lX2NvdW50X3NwZWNpZXNfYWdncmVnKS9hcy5udW1lcmljKG5hbWVzKHRhYmxlKGFjY2VwdGVkX25hbWVfY291bnRfc3BlY2llc19hZ2dyZWcpKSkgICMgTnVtYmVyIG9mIGNhdGVnb3JpZXMgd2l0aCAxLCAyLCAzLCAuLi4gb2NjdXJyZW5jZXMgb2YgdGhlIHNhbWUgc3BlY2llcwoKIyBDb21wYXJlIHRoZSBjb3JyZWN0ZWQgb2JzZXJ2ZWQgZGlzdHJpYnV0aW9uIHdpdGggdGhlIHRoZW9yZXRpY2FsIGN1cnZlCmdncGxvdChDZXRhY2VhX29jY19hZ2dyZWdbQ2V0YWNlYV9vY2NfYWdncmVnJGFjY2VwdGVkX3Jhbms9PSJzcGVjaWVzIixdLCAKICAgICAgIGFlcyh4PWFjY2VwdGVkX25hbWVfY291bnQsCiAgICAgICAgICAgeT1hY2NlcHRlZF9uYW1lX2NvdW50X2NhdGVnb3JpZXNfYWdncmVnW2FzLmZhY3RvcihhY2NlcHRlZF9uYW1lX2NvdW50KV0sIAogICAgICAgICAgIGZpbGw9YWNjZXB0ZWRfcmFuaykpICsKICBnZW9tX3BvaW50KCkgKwogIAogIGFubm90YXRlKCJsaW5lIiwgeCA9IDE6bWF4KGFjY2VwdGVkX25hbWVfY291bnRfc3BlY2llc19hZ2dyZWcpLCB5PSBkZW5zX2FnZ3JlZwogICAgKm1heCgodGFibGUoYWNjZXB0ZWRfbmFtZV9jb3VudF9zcGVjaWVzX2FnZ3JlZykvYXMubnVtZXJpYyhuYW1lcyh0YWJsZShhY2NlcHRlZF9uYW1lX2NvdW50X3NwZWNpZXNfYWdncmVnKSkpKVthcy5mYWN0b3IoYWNjZXB0ZWRfbmFtZV9jb3VudF9zcGVjaWVzX2FnZ3JlZyldKSAvbWF4KGRlbnNfYWdncmVnKSkgKwogIAogIHNjYWxlX3hfY29udGludW91cyhuYW1lID0gIk51bWJlciBvZiBvY2N1cnJlbmNlcyBieSBhY2NlcHRlZCBuYW1lIikgKwogIHNjYWxlX3lfY29udGludW91cyh0cmFucyA9ICJsb2cxMCIsIG5hbWUgPSAiTnVtYmVyIG9mIGNvcnJlc3BvbmRpbmcgYWNjZXB0ZWQgbmFtZXMgKGxvZy1zY2FsZSkiKSArCiAgc2NhbGVfZmlsbF9kaXNjcmV0ZShuYW1lPSJPYnNlcnZlZCBkaXN0cmlidXRpb24iKSArCiAgdGhlbWUocGFuZWwuZ3JpZC5tYWpvci54ID0gZWxlbWVudF9ibGFuaygpLCAKICAgICAgICBwYW5lbC5ncmlkLm1ham9yLnkgPSBlbGVtZW50X2JsYW5rKCkpICsKICBnZ3RpdGxlKCJDb21wYXJpc29uIGJldHdlZW4gZXhwZWN0ZWQgYW5kIG9ic2VydmVkIGRpc3RyaWJ1dGlvbnMgb2YgbnVtYmVyIG9mIG9jY3VycmVuY2VzLCBhZnRlciBhZ2dyZWdhdGluZyBpbiBnZW9wbGF0ZXMiKSArCiAgZmFjZXRfZ3JpZChhY2NlcHRlZF9yYW5rIH4gLiwgc2NhbGVzID0gImZyZWUiKQoKYWNjZXB0ZWRfbmFtZV9jb3VudF9zcGVjaWVzX2FnZ3JlZyA8LSBDZXRhY2VhX29jY19hZ2dyZWdbQ2V0YWNlYV9vY2NfYWdncmVnJGFjY2VwdGVkX3Jhbms9PSJzcGVjaWVzIixdJGFjY2VwdGVkX25hbWVfY291bnQKZGVuc19hZ2dyZWcgPC0gc2FwcGx5KDE6bWF4KGFjY2VwdGVkX25hbWVfY291bnRfc3BlY2llc19hZ2dyZWcpLCBmdW5jdGlvbihuKXsKICAgICBleHBlY3RlZF9kaXN0cmlidXRpb24obiwgb21lZ2EsIENldGFjZWFfb2NjX2FnZ3JlZ1tDZXRhY2VhX29jY19hZ2dyZWckYWNjZXB0ZWRfcmFuaz09InNwZWNpZXMiLF0kc3RyYXRpZ3JhcGhpY19yYW5nZV9kdXJhdGlvbikkdmFsdWUKICAgIH0pCmFjY2VwdGVkX25hbWVfY291bnRfY2F0ZWdvcmllc19hZ2dyZWcgPC0gdGFibGUoYWNjZXB0ZWRfbmFtZV9jb3VudF9zcGVjaWVzX2FnZ3JlZykvYXMubnVtZXJpYyhuYW1lcyh0YWJsZShhY2NlcHRlZF9uYW1lX2NvdW50X3NwZWNpZXNfYWdncmVnKSkpICAjIE51bWJlciBvZiBjYXRlZ29yaWVzIHdpdGggMSwgMiwgMywgLi4uIG9jY3VycmVuY2VzIG9mIHRoZSBzYW1lIHNwZWNpZXMKYGBgCgokXHRvJCBUaGUgY29ycmVzcG9uZGVuY2UgaXMgc3RpbGwgZ29vZCwgZXhjZXB0IGZvciB0d28gdGF4YToKCmBgYHtyfQp0YWJsZShkcm9wbGV2ZWxzKENldGFjZWFfb2NjX2FnZ3JlZ1tDZXRhY2VhX29jY19hZ2dyZWckYWNjZXB0ZWRfcmFuaz09InNwZWNpZXMiLF1bYWNjZXB0ZWRfbmFtZV9jb3VudF9zcGVjaWVzX2FnZ3JlZz4xMCxdJGFjY2VwdGVkX25hbWUpKQpgYGAKCmBgYHtyIGZpZy53aWR0aD0xMCwgZmlnLmFzcD0wLjV9CmNvbmRpdGlvbnMgPC0gQ2V0YWNlYV9vY2MkYWNjZXB0ZWRfcmFuayA9PSJzcGVjaWVzIgoKcDEgPC0gZ2dwbG90KENldGFjZWFfb2NjW2NvbmRpdGlvbnMsXSwgYWVzKHg9LWFnZV9ydW5pZikpICsKICBnZW9tX2hpc3RvZ3JhbShiaW53aWR0aCA9IDAuNSwgYWxwaGE9MC41LCBmaWxsPU5BLCBjb2w9InJlZCIpICsKICB4bGltKC1tYXgoQ2V0YWNlYV9vY2NbY29uZGl0aW9ucyxdJGFnZV9ydW5pZiktMSwgMSkgKwogIHlsaW0oMCwgNzApICsKICB0aGVtZV92b2lkKCkKCnAyIDwtIGdncGxvdChDZXRhY2VhX29jY19zYW1wbGVkLCBhZXMoeD0tYWdlX3J1bmlmKSkgKwogIGdlb21faGlzdG9ncmFtKGJpbndpZHRoID0gMC41LCBhbHBoYT0wLjUsIGZpbGw9ImJsdWUiKSArCiAgeGxpbSgtbWF4KENldGFjZWFfb2NjW2NvbmRpdGlvbnMsXSRhZ2VfcnVuaWYpLTEsIDEpICsKICB5bGltKDAsIDcwKSArCiAgdGhlbWVfdm9pZCgpCgpwMyA8LSBnZ3Bsb3QoQ2V0YWNlYV9vY2NfYWdncmVnW0NldGFjZWFfb2NjX2FnZ3JlZyRhY2NlcHRlZF9yYW5rID09InNwZWNpZXMiLF0sIGFlcyh4PS1hZ2VfcnVuaWYpKSArCiAgZ2VvbV9oaXN0b2dyYW0oYmlud2lkdGggPSAwLjUsIGFscGhhPTAuNSwgZmlsbD0iZ3JlZW4iKSArCiAgeGxpbSgtbWF4KENldGFjZWFfb2NjW2NvbmRpdGlvbnMsXSRhZ2VfcnVuaWYpLTEsIDEpICsKICB5bGltKDAsIDcwKSArCiAgdGhlbWVfdm9pZCgpCgojIHAxICsgYW5ub3RhdGlvbl9jdXN0b20oZ2dwbG90R3JvYihwMikpICsgZ2d0aXRsZSgiSW5pdGlhbCBvY2N1cnJlbmNlcyBkaXN0cmlidXRpb24gKHJlZCkgYW5kIGNvbXBhcmlzb24gYWZ0ZXIgc3ViLXNhbXBsaW5nIChibHVlKSIpCiMgCiMgcDEgKyBhbm5vdGF0aW9uX2N1c3RvbShnZ3Bsb3RHcm9iKHAzKSkgKyBnZ3RpdGxlKCJJbml0aWFsIG9jY3VycmVuY2VzIGRpc3RyaWJ1dGlvbiAocmVkKSBhbmQgY29tcGFyaXNvbiBhZnRlciBhZ2dyZWdhdGluZyBpbiBnZW9wbGF0ZXMgKGdyZWVuKSIpCgpwMSArIGFubm90YXRpb25fY3VzdG9tKGdncGxvdEdyb2IocDIpKSArIGFubm90YXRpb25fY3VzdG9tKGdncGxvdEdyb2IocDMpKSArIGdndGl0bGUoIkluaXRpYWwgb2NjdXJyZW5jZXMgZGlzdHJpYnV0aW9uIChyZWQpIGFuZCBjb21wYXJpc29uIGFmdGVyIHN1Yi1zYW1wbGluZyAoYmx1ZSkgb3IgYWdncmVnYXRpbmcgaW4gZ2VvcGxhdGVzIChncmVlbikiKQpgYGAKCiRcdG8kIERlbGltaXRpbmcgYnkgZ2VvbG9naWNhbCBwbGF0ZXMgKCsgYWdlKSBpbnN0ZWFkIG9mIGNvdW50cmllcyAoKyBhZ2UpIGxlYWRzIHRvIHNpbWlsYXIgZGlzdHJpYnV0aW9ucywgc28gd2Ugd2lsbCBrZWVwIGl0LgoKIyMgQ2hlY2sgdGhhdCB0aGUgc2FtcGxpbmcgbWV0aG9kcyBkbyBub3QgaW50cm9kdWNlIGJpYXNlcyBpbiB0aGUgcmVwYXJ0aXRpb24gYmV0d2VlbiBPZG9udG9jZXRpIGFuZCBNeXN0aWNldGkKCk15c3RlY2V0ZXMgYXJlIHVzdWFsbHkgbGFyZ2VyIHRoYW4gb2RvbnRvY2V0ZXMsIGFuZCBzaXplIGlzIGFzc29jaWF0ZWQgd2l0aCBhIHdpZGVyIGdlb2dyYXBoaWMgcmFuZ2Ugc28gc2luY2Ugd2UgYXJlIHN1YnNhbXBsaW5nIG9jY3VycmVuY2VzIGFjY29yZGluZyB0byBnZW9sb2dpY2FsIGZvcm1hdGlvbiB3ZSBtYXkgYmUgYmlhc2luZyBvdXIgZGF0YSB0b3dhcmRzIG1vcmUgd2lkZXNwcmVhZCBzcGVjaWVzLCB0aGVyZWZvcmUgdG93YXJkcyBteXN0ZWNldGVzLgoKTG9vayBhdCB0aGUgZmFtaWxpZXMgZmlyc3Q6CgpgYGB7ciBmaWcuaGVpZ2h0PTZ9CmZhbWlsaWVzIDwtIHJiaW5kKENldGFjZWFfb2NjID0gQ2V0YWNlYV9vY2NbQ2V0YWNlYV9vY2MkYWNjZXB0ZWRfcmFuaz09InNwZWNpZXMiLF0sCiAgICAgICAgICAgICAgICAgIENldGFjZWFfb2NjX3NhbXBsZWQgPSBDZXRhY2VhX29jY19zYW1wbGVkLAogICAgICAgICAgICAgICAgICBDZXRhY2VhX29jY19hZ2dyZWcgPSBDZXRhY2VhX29jY19hZ2dyZWdbQ2V0YWNlYV9vY2NfYWdncmVnJGFjY2VwdGVkX3Jhbms9PSJzcGVjaWVzIixdKSAlPiUKICAgICAgICAgICAgdGliYmxlOjpyb3duYW1lc190b19jb2x1bW4odmFyID0gIkRhdGFzZXQiKQoKZmFtaWxpZXMgPC0gZmFtaWxpZXNbLGMoIkRhdGFzZXQiLCAiZmFtaWx5IildCmZhbWlsaWVzJERhdGFzZXQgPC0gc2FwcGx5KGZhbWlsaWVzJERhdGFzZXQsIGdzdWIsIHBhdHRlcm49IlxcLi4qIiwgcmVwbGFjZW1lbnQ9IiIpCgpnZ3Bsb3QoZmFtaWxpZXNbZmFtaWxpZXMkZmFtaWx5ICE9ICJOT19GQU1JTFlfU1BFQ0lGSUVEIixdLCBhZXMoeCA9IERhdGFzZXQsIGZpbGwgPSBmYW1pbHkpKSArIAogICAgZ2VvbV9iYXIocG9zaXRpb249ImZpbGwiLCBjb2w9ImJsYWNrIikKYGBgCgokXHRvJCBUaGUgZmFtaWx5IGRpc3RyaWJ1dGlvbnMgdmFyeSBhIGJpdCBhZnRlciBzdWJzYW1wbGluZywgYnV0IGJlY2F1c2Ugb2YgdGhlIGxpbWl0ZWQgbnVtYmVyIG9mIHNwZWNpZXMgYnkgZmFtaWx5IHRoZSBmYWN0IHRoYXQgd2UgY29ycmVjdGVkIHRoZSBvdmVyc2FtcGxpbmcgb2Ygc29tZSBzcGVjaWVzIGNvdWxkIGhhdmUgYSBkaXNwcm9wb3J0aW9uYXRlIGVmZmVjdC4KCkxldCdzIGxvb2sgcmF0aGVyIGF0IGEgaGlnaGVyIHRheG9ub21pYyByYW5rLCBieSBpbXBvcnRpbmcgdGhlIHRvcG9sb2d5IG9mIGNldGFjZWFuIGZhbWlsaWVzIChmcm9tIE1hcnggZXQgYWwuIDIwMTYpOgoKYGBge3IgZmlnLndpZHRoPTEwLCBpbmNsdWRlPUZ9CmZhbWlsaWVzX3RyZWUgPC0gYXBlOjpyZWFkLnRyZWUoIi4uL2Jqb2VsbGUtc3RyYXRpZ3JhcGhpY19hZ2VfdW5jZXJ0YWludHlfU0ktOWJiY2VmMi9jZXRhY2VhbnNfZGF0YS9mb3NzaWxzL2ZhbWlsaWVzLnRyZSIpCmdndHJlZShmYW1pbGllc190cmVlKSArCiAgZ2VvbV90aXBsYWIoKSArCiAgZ2VvbV9ub2RlbGFiKCkgKyAKICBnZ3RpdGxlKCJUb3BvbG9neSBvZiBjZXRhY2VhbiBmYW1pbGllcyIpICsKICB4bGltKDAsIDgpCgpmYW1pbGllc190cmVlX09kb250b2NldGkgPC0gY2FzdG9yOjpnZXRfc3VidHJlZV9hdF9ub2RlKGZhbWlsaWVzX3RyZWUsICJPZG9udG9jZXRpIikkc3VidHJlZQpnZ3RyZWUoZmFtaWxpZXNfdHJlZV9PZG9udG9jZXRpKSArCiAgZ2VvbV90aXBsYWIoKSArCiAgZ2VvbV9ub2RlbGFiKCkgKyAKICBnZ3RpdGxlKCJUb3BvbG9neSBvZiBvZG9udG9jZXRlIGZhbWlsaWVzIikgKwogIHhsaW0oMCwgNSkKCmZhbWlsaWVzX3RyZWVfTXlzdGljZXRpIDwtIGNhc3Rvcjo6Z2V0X3N1YnRyZWVfYXRfbm9kZShmYW1pbGllc190cmVlLCAiTXlzdGljZXRpIikkc3VidHJlZQpnZ3RyZWUoZmFtaWxpZXNfdHJlZV9NeXN0aWNldGkpICsKICBnZW9tX3RpcGxhYigpICsKICBnZW9tX25vZGVsYWIoKSArIAogIGdndGl0bGUoIlRvcG9sb2d5IG9mIG15c3RpY2V0ZSBmYW1pbGllcyIpICsKICB4bGltKDAsIDUpCgpmYW1pbGllc190cmVlX1N0ZW0gPC0gY2FzdG9yOjpnZXRfc3VidHJlZV93aXRoX3RpcHMoZmFtaWxpZXNfdHJlZSwgb21pdF90aXBzID0gYyhmYW1pbGllc190cmVlX09kb250b2NldGkkdGlwLmxhYmVsLCBmYW1pbGllc190cmVlX015c3RpY2V0aSR0aXAubGFiZWwpKSRzdWJ0cmVlCmdndHJlZShmYW1pbGllc190cmVlX1N0ZW0pICsKICBnZW9tX3RpcGxhYigpICsKICBnZW9tX25vZGVsYWIoKSArIAogIGdndGl0bGUoIlRvcG9sb2d5IG9mIGFyY2hlb2NldGUgZmFtaWxpZXMiKSArCiAgeGxpbSgwLCAzKQpgYGAKCmBgYHtyLCBmaWcuYXNwPTAuNCwgZmlnLndpZHRoPTh9Ck9kb250b2NldGlfZmFtaWxpZXMgPC0gYyhmYW1pbGllc190cmVlX09kb250b2NldGlbYygidGlwLmxhYmVsIiwgIm5vZGUubGFiZWwiKV0sICJLZW50cmlvZG9udGlkYWUiLCAiU3F1YWxvemlwaGlpZGFlIikKTXlzdGljZXRpX2ZhbWlsaWVzIDwtIGZhbWlsaWVzX3RyZWVfTXlzdGljZXRpW2MoInRpcC5sYWJlbCIsICJub2RlLmxhYmVsIildCmFyY2hhZW9jZXRlX2ZhbWlsaWVzIDwtIGZhbWlsaWVzX3RyZWVfU3RlbVtjKCJ0aXAubGFiZWwiLCAibm9kZS5sYWJlbCIpXQoKZmFtaWx5X3RvX3RheG9ub21pY19ncm91cCA8LSBmdW5jdGlvbihmYW1pbHkpewogIHJldHVybihjKCJPZG9udG9jZXRpIiwgIk15c3RpY2V0aSIsICJhcmNoYWVvY2V0ZXMiKVsKICAgIGdyZXAocGF0dGVybiA9IGZhbWlseSwKICAgICAgICAgeCA9IGxpc3QoT2RvbnRvY2V0aV9mYW1pbGllcywgTXlzdGljZXRpX2ZhbWlsaWVzLCBhcmNoYWVvY2V0ZV9mYW1pbGllcykpXSkKICB9CgpmYW1pbGllcyRUYXhvbm9taWMuZ3JvdXAgPC0gYXMuY2hhcmFjdGVyKHNhcHBseShmYW1pbGllcyRmYW1pbHksIGZhbWlseV90b190YXhvbm9taWNfZ3JvdXApKQpnZ3Bsb3QoZmFtaWxpZXNbZmFtaWxpZXMkZmFtaWx5ICE9ICJOT19GQU1JTFlfU1BFQ0lGSUVEIixdLCBhZXMoeCA9IERhdGFzZXQsIGZpbGwgPSBUYXhvbm9taWMuZ3JvdXApKSArIAogICAgZ2VvbV9iYXIocG9zaXRpb249ImZpbGwiLCBjb2w9ImJsYWNrIikKCmdncGxvdChmYW1pbGllc1tmYW1pbGllcyRmYW1pbHkgIT0gIk5PX0ZBTUlMWV9TUEVDSUZJRUQiICYgZmFtaWxpZXMkVGF4b25vbWljLmdyb3VwICE9ICJhcmNoYWVvY2V0ZXMiLF0sIGFlcyh4ID0gRGF0YXNldCwgZmlsbCA9IFRheG9ub21pYy5ncm91cCkpICsKICBnZW9tX2Jhcihwb3NpdGlvbj0iZmlsbCIsIGNvbD0iYmxhY2siKQpgYGAKCiRcdG8kIFRoZXJlIGlzIGEgc21hbGxlciBwcm9wb3J0aW9uIG9mIGFyY2hlb2NldGUgb2NjdXJyZW5jZXMgYWZ0ZXIgZWl0aGVyIHNhbXBsaW5nLCBiZWNhdXNlIGEgaHVnZSBjbHVzdGVyIGlzIHN1YnNhbXBsZWQgYXJvdW5kIDM1IE15IGFnbywgYnV0IHRoaXMgZWZmZWN0IGlzIGV4cGVjdGVkLiBIb3dldmVyLCBmb3IgdGhlIE15c3RpY2V0aSB2cy4gT2RvdG9jZXRpIHRoZXJlIGlzIG5vIGh1Z2UgYXBwYXJlbnQgYmlhcywgZXNwZWNpYWxseSB3aXRoIHRoZSBhZ2dyZWdhdGluZyBtZXRob2QuCgpgYGB7cn0KIyB3cml0ZShDZXRhY2VhX29jY19hZ2dyZWdbQ2V0YWNlYV9vY2NfYWdncmVnJGFjY2VwdGVkX3JhbmsgPT0ic3BlY2llcyIsXSRhZ2VfcnVuaWYsIAojICAgICAgIGZpbGUgPSAiLi4vZGF0YS1jZXRhY2VhbnMvQ2V0YWNlYV9hZ2VfcnVuaWZfYWdlX3NwZWNpZXNfY29ycmVjdGVkLmNzdiIsIAojICAgICAgIHNlcCA9ICI7ICIsIAojICAgICAgIG5jb2x1bW5zID0gZGltKENldGFjZWFfb2NjX2FnZ3JlZ1tDZXRhY2VhX29jY19hZ2dyZWckYWNjZXB0ZWRfcmFuayA9PSJzcGVjaWVzIixdKVsxXSkKd3JpdGUudGFibGUoQ2V0YWNlYV9vY2NfYWdncmVnW0NldGFjZWFfb2NjX2FnZ3JlZyRhY2NlcHRlZF9yYW5rID09ICJzcGVjaWVzIiwgYygibWluX21hIiwgIm1heF9tYSIpXSwKICAgICAgICAgICAgZmlsZT0iLi4vZGF0YS1jZXRhY2VhbnMvQ2V0YWNlYV9vY2N1cnJlbmNlc19taW5fbWF4X2FnZV9zcGVjaWVzX2NvcnJlY3RlZC5jc3YiLCBzZXA9IiwiLCByb3cubmFtZXM9RkFMU0UsIGNvbC5uYW1lcz1GQUxTRSkKCndyaXRlLnRhYmxlKENldGFjZWFfb2NjX2FnZ3JlZ1tDZXRhY2VhX29jY19hZ2dyZWckYWNjZXB0ZWRfcmFuayAlaW4lIGMoInNwZWNpZXMiLCAiZ2VudXMiKSwgYygibWluX21hIiwgIm1heF9tYSIpXSwKICAgICAgICAgICAgZmlsZT0iLi4vZGF0YS1jZXRhY2VhbnMvQ2V0YWNlYV9vY2N1cnJlbmNlc19taW5fbWF4X2FnZV9zcGVjaWVzX2dlbmVyYV9jb3JyZWN0ZWQuY3N2Iiwgc2VwPSIsIiwgcm93Lm5hbWVzPUZBTFNFLCBjb2wubmFtZXM9RkFMU0UpCmBgYAoKYGBge3IgZmlnLmFzcD0wLjMsIGZpZy53aWR0aD0xMH0KZ2dwbG90KENldGFjZWFfb2NjX2FnZ3JlZ1tDZXRhY2VhX29jY19hZ2dyZWckYWNjZXB0ZWRfcmFuayA9PSAic3BlY2llcyIsXSwgYWVzKHg9LWFnZV9ydW5pZiwgeT1ybm9ybShsZW5ndGgoYWdlX3J1bmlmKSwgMSwgMC4wMykpKSArCiAgZ2VvbV9wb2ludChjZXg9MS41LCBhbHBoYT0wLjUpICsKICBzY2FsZV94X2NvbnRpbnVvdXMobmFtZSA9ICJUaW1lIChNeSkiKSArCiAgc2NhbGVfeV9jb250aW51b3VzKG5hbWUgPSAiT2NjdXJyZW5jZXMiLCBsaW1pdHMgPSBjKDAuNywgMS4zKSkgKwogIHNjYWxlX2ZpbGxfZGlzY3JldGUobmFtZT0iQWNjZXB0ZWQgcmFuayIpICsKICB0aGVtZShwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIGF4aXMubGluZS54ID0gZWxlbWVudF9saW5lKHNpemUgPSAwLjUsIGxpbmV0eXBlID0gInNvbGlkIiwgY29sb3VyID0gImJsYWNrIiksCiAgICAgICAgYXhpcy50ZXh0LnkgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50aWNrcy55ID0gZWxlbWVudF9ibGFuaygpKSArCiAgZ2d0aXRsZShwYXN0ZSgiUmVwYXJ0aXRpb24gb2YiLCBkaW0oY2V0YWNlYV9wYmRiKVsxXSwgInJlY29yZGVkIG9jY3VycmVuY2VzIHRocm91Z2ggdGltZSIpKQpgYGAKCiMgRmFzdGVyIGdlbnVzLWxldmVsIGFuYWx5c2lzCgpBcHBseSB0aGUgc2FtZSB0cmFuc2Zvcm1hdGlvbnMgYXQgdGhlIGdlbmVyaWMgbGV2ZWwgdG8gcGVyZm9ybSB0aGUgYW5hbHlzaXMgZmFzdGVyLgoKYGBge3J9CkNldGFjZWFfb2NjX2FnZ3JlZ19nZW4gPC0gYygpCgojIEJyb3dzZSBhbGwgZm9ybWF0aW9ucwpmb3JtYXRpb25zIDwtIGxldmVscyhkcm9wbGV2ZWxzKENldGFjZWFfb2NjJGZvcm1hdGlvbikpCmZvciAoZm9ybSBpbiBmb3JtYXRpb25zWy13aGljaChmb3JtYXRpb25zPT0iIildKXsKICBDZXRhY2VhX29jY19mb3JtIDwtIENldGFjZWFfb2NjW0NldGFjZWFfb2NjJGZvcm1hdGlvbj09Zm9ybSxdCiAgCiAgIyBCcm93c2UgYWxsIGdlbmVyYSBpbiBlYWNoIGZvcm1hdGlvbiAmIHNhbXBsZSBvbmx5IDEgb2NjdXJyZW5jZQogIGdlbmVyYSA8LSBsZXZlbHMoZHJvcGxldmVscyhDZXRhY2VhX29jY19mb3JtJGdlbnVzKSkKICBmb3IgKGdlbiBpbiBnZW5lcmEpewogICAgQ2V0YWNlYV9vY2NfYWdncmVnX2dlbiA8LSByYmluZChDZXRhY2VhX29jY19hZ2dyZWdfZ2VuLCBzYW1wbGVfbihDZXRhY2VhX29jY19mb3JtW0NldGFjZWFfb2NjX2Zvcm0kZ2VudXM9PWdlbixdLCBzaXplID0gMSkpCiAgfQp9CgojIEdlbmVyYSBmb3Igd2hpY2ggdGhlIGdlb2xvZ2ljYWwgZm9ybWF0aW9uIGlzIG1pc3NpbmcKIyBCcm93c2UgYWxsIGdlb3BsYXRlcwpnZW9wbGF0ZXMgPC0gbGV2ZWxzKGRyb3BsZXZlbHMoQ2V0YWNlYV9vY2NbQ2V0YWNlYV9vY2MkZm9ybWF0aW9uPT0iIixdJGdlb3BsYXRlKSkKZm9yIChncCBpbiBnZW9wbGF0ZXMpewogIENldGFjZWFfb2NjX2dwIDwtIENldGFjZWFfb2NjW0NldGFjZWFfb2NjJGZvcm1hdGlvbj09IiIgJiBDZXRhY2VhX29jYyRnZW9wbGF0ZT09Z3AsXQogIAogICMgQnJvd3NlIGFsbCBlYXJseSBzdHJhdGlncmFwaGljIGludGVydmFscwogIGVhcmx5X2ludGVydmFscyA8LSBsZXZlbHMoZHJvcGxldmVscyhDZXRhY2VhX29jY19ncCRlYXJseV9pbnRlcnZhbCkpCiAgZm9yIChlaSBpbiBlYXJseV9pbnRlcnZhbHMpewogICAgQ2V0YWNlYV9vY2NfZ3BfZWkgPC0gQ2V0YWNlYV9vY2NfZ3BbQ2V0YWNlYV9vY2NfZ3AkZWFybHlfaW50ZXJ2YWw9PWVpLF0KICAgIAogICAgIyBCcm93c2UgYWxsIGdlbmVyYSAmIHNhbXBsZSBvbmx5IDEgb2NjdXJyZW5jZQogICAgZ2VuZXJhIDwtIGxldmVscyhkcm9wbGV2ZWxzKENldGFjZWFfb2NjX2dwX2VpJGdlbnVzKSkKICAgIGZvciAoZ2VuIGluIGdlbmVyYSl7CiAgICAgIENldGFjZWFfb2NjX2FnZ3JlZ19nZW4gPC0gcmJpbmQoQ2V0YWNlYV9vY2NfYWdncmVnX2dlbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNhbXBsZV9uKENldGFjZWFfb2NjX2dwX2VpW0NldGFjZWFfb2NjX2dwX2VpJGdlbnVzPT1nZW4sXSwgc2l6ZSA9IDEpKQogICAgfQogIH0KfQoKZGF0YS5mcmFtZShDZXRhY2VhX29jYyA9IGMoZGltKENldGFjZWFfb2NjKVsxXSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGRpbShDZXRhY2VhX29jY1tDZXRhY2VhX29jYyRhY2NlcHRlZF9yYW5rICVpbiUgYygic3BlY2llcyIsICJnZW51cyIpLF0pWzFdKSwKICAgICAgICAgICBDZXRhY2VhX29jY19hZ2dyZWdfZ2VuID0gYyhkaW0oQ2V0YWNlYV9vY2NfYWdncmVnX2dlbilbMV0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkaW0oQ2V0YWNlYV9vY2NfYWdncmVnX2dlbltDZXRhY2VhX29jY19hZ2dyZWdfZ2VuJGFjY2VwdGVkX3JhbmsgJWluJSBjKCJzcGVjaWVzIiwgImdlbnVzIiksXSlbMV0pLAogICAgICAgICAgIHJlbW92ZWQgPSBjKGRpbShDZXRhY2VhX29jYylbMV0tZGltKENldGFjZWFfb2NjX2FnZ3JlZ19nZW4pWzFdLAogICAgICAgICAgICAgICAgICAgICAgIGRpbShDZXRhY2VhX29jY1tDZXRhY2VhX29jYyRhY2NlcHRlZF9yYW5rICVpbiUgYygic3BlY2llcyIsICJnZW51cyIpLF0pWzFdLWRpbShDZXRhY2VhX29jY19hZ2dyZWdfZ2VuW0NldGFjZWFfb2NjX2FnZ3JlZ19nZW4kYWNjZXB0ZWRfcmFuayAlaW4lIGMoInNwZWNpZXMiLCAiZ2VudXMiKSxdKVsxXSksCiAgICAgICAgICAgcm93Lm5hbWVzID0gYygiTnVtYmVyIG9mIG9jY3VycmVuY2VzIiwgIk51bWJlciBvZiBvY2N1cnJlbmNlcyAoc3BlY2llcyBhbmQgZ2VuZXJhIG9ubHkpIikpCmBgYAoKTW9yZSBvY2N1cnJlbmNlcyByZW1haW4gYWZ0ZXIgYWdncmVnYXRpbmcgd2l0aCB0aGlzIG5ldyBtZXRob2QuIExldCdzIGNvbXBhcmUgYWdhaW4gd2l0aCB0aGUgdGhlb3JldGljYWwgZGlzdHJpYnV0aW9uOgoKYGBge3IgZmlnLndpZHRoPTEwLCBmaWcuYXNwPTAuNH0KIyBSZWNvdW50IHRoZSBudW1iZXIgb2Ygb2NjdXJyZW5jZXMgd2l0aCB0aGUgc2FtZSBnZW51cyBhZnRlciB0aGUgYWdncmVnYXRpb24KQ2V0YWNlYV9vY2MkZ2VudXNfY291bnQgPC0gc2FwcGx5KENldGFjZWFfb2NjJGdlbnVzLCBmdW5jdGlvbih4KXt0YWJsZShDZXRhY2VhX29jYyRnZW51cylbeF19KQpDZXRhY2VhX29jY19hZ2dyZWdfZ2VuJGdlbnVzX2NvdW50IDwtIHNhcHBseShDZXRhY2VhX29jY19hZ2dyZWdfZ2VuJGdlbnVzLCBmdW5jdGlvbih4KXt0YWJsZShDZXRhY2VhX29jY19hZ2dyZWdfZ2VuJGdlbnVzKVt4XX0pCgpvbWVnYSA8LSAwLjMKZ2VudXNfY291bnQgPC0gQ2V0YWNlYV9vY2NbQ2V0YWNlYV9vY2MkYWNjZXB0ZWRfcmFuayAlaW4lIGMoInNwZWNpZXMiLCAiZ2VudXMiKSxdJGdlbnVzX2NvdW50CmRlbnMgPC0gc2FwcGx5KDE6bWF4KGdlbnVzX2NvdW50KSwgZnVuY3Rpb24obil7IGV4cGVjdGVkX2Rpc3RyaWJ1dGlvbihuLCBvbWVnYSwgQ2V0YWNlYV9vY2NbQ2V0YWNlYV9vY2MkYWNjZXB0ZWRfcmFuayAlaW4lIGMoInNwZWNpZXMiLCAiZ2VudXMiKSxdJHN0cmF0aWdyYXBoaWNfcmFuZ2VfZHVyYXRpb24pJHZhbHVlIH0pCmdlbnVzX2NvdW50X2NhdGVnb3JpZXMgPC0gdGFibGUoZ2VudXNfY291bnQpL2FzLm51bWVyaWMobmFtZXModGFibGUoZ2VudXNfY291bnQpKSkgICMgTnVtYmVyIG9mIGNhdGVnb3JpZXMgd2l0aCAxLCAyLCAzLCAuLi4gb2NjdXJyZW5jZXMgb2YgdGhlIHNhbWUgZ2VudXMKCiMgQ29tcGFyZSB0aGUgaW5pdGlhbCBvYnNlcnZlZCBkaXN0cmlidXRpb24gd2l0aCB0aGUgdGhlb3JldGljYWwgY3VydmUKZ2dwbG90KENldGFjZWFfb2NjW0NldGFjZWFfb2NjJGFjY2VwdGVkX3JhbmsgJWluJSBjKCJzcGVjaWVzIiwgImdlbnVzIiksXSwgCiAgICAgICBhZXMoeD1nZW51c19jb3VudCwgCiAgICAgICAgICAgeT1nZW51c19jb3VudF9jYXRlZ29yaWVzW2FzLmZhY3RvcihnZW51c19jb3VudCldLCAKICAgICAgICAgICBmaWxsPWFjY2VwdGVkX3JhbmspKSArCiAgZ2VvbV9wb2ludCgpICsKICAKICBhbm5vdGF0ZSgibGluZSIsIHggPSAxOm1heChnZW51c19jb3VudCksIHk9IGRlbnMKICAgICptYXgoKHRhYmxlKGdlbnVzX2NvdW50KS9hcy5udW1lcmljKG5hbWVzKHRhYmxlKGdlbnVzX2NvdW50KSkpKVthcy5mYWN0b3IoZ2VudXNfY291bnQpXSkgL21heChkZW5zKSkrCiAgCiAgc2NhbGVfeF9jb250aW51b3VzKG5hbWUgPSAiTnVtYmVyIG9mIG9jY3VycmVuY2VzIGJ5IGdlbnVzIikgKwogIHNjYWxlX3lfY29udGludW91cyh0cmFucyA9ICJsb2cxMCIsIG5hbWUgPSAiTnVtYmVyIG9mIGNvcnJlc3BvbmRpbmcgZ2VuZXJhIChsb2ctc2NhbGUpIikgKwogIHNjYWxlX2ZpbGxfZGlzY3JldGUobmFtZT0iT2JzZXJ2ZWQgZGlzdHJpYnV0aW9uIikgKwogIHRoZW1lKHBhbmVsLmdyaWQubWFqb3IueCA9IGVsZW1lbnRfYmxhbmsoKSwgCiAgICAgICAgcGFuZWwuZ3JpZC5tYWpvci55ID0gZWxlbWVudF9ibGFuaygpKSArCiAgZ2d0aXRsZSgiQ29tcGFyaXNvbiBiZXR3ZWVuIGV4cGVjdGVkIGFuZCBvYnNlcnZlZCBkaXN0cmlidXRpb25zIG9mIG51bWJlciBvZiBvY2N1cnJlbmNlcyIpCgpnZW51c19jb3VudF9hZ2dyZWcgPC0gQ2V0YWNlYV9vY2NfYWdncmVnX2dlbltDZXRhY2VhX29jY19hZ2dyZWdfZ2VuJGFjY2VwdGVkX3JhbmsgJWluJSBjKCJzcGVjaWVzIiwgImdlbnVzIiksXSRnZW51c19jb3VudApkZW5zX2FnZ3JlZyA8LSBzYXBwbHkoMTptYXgoZ2VudXNfY291bnRfYWdncmVnKSwgZnVuY3Rpb24obil7CiAgICAgZXhwZWN0ZWRfZGlzdHJpYnV0aW9uKG4sIG9tZWdhLCBDZXRhY2VhX29jY19hZ2dyZWdfZ2VuW0NldGFjZWFfb2NjX2FnZ3JlZ19nZW4kYWNjZXB0ZWRfcmFuayAlaW4lIGMoInNwZWNpZXMiLCAiZ2VudXMiKSxdJHN0cmF0aWdyYXBoaWNfcmFuZ2VfZHVyYXRpb24pJHZhbHVlCiAgICB9KQoKIyBOdW1iZXIgb2YgY2F0ZWdvcmllcyB3aXRoIDEsIDIsIDMsIC4uLiBvY2N1cnJlbmNlcyBvZiB0aGUgc2FtZSBnZW51cwpnZW51c19jb3VudF9jYXRlZ29yaWVzX2FnZ3JlZyA8LSB0YWJsZShnZW51c19jb3VudF9hZ2dyZWcpL2FzLm51bWVyaWMobmFtZXModGFibGUoZ2VudXNfY291bnRfYWdncmVnKSkpCgojIE51bWJlciBvZiBvY2N1cnJlbmNlcyBieSBjYXRlZ29yeQpDZXRhY2VhX29jY19hZ2dyZWdfZ2VuJGdlbnVzX2NhdGVnb3JpZXNfY291bnQgPC0gYXMubnVtZXJpYyhnZW51c19jb3VudF9jYXRlZ29yaWVzX2FnZ3JlZ1thcy5mYWN0b3IoQ2V0YWNlYV9vY2NfYWdncmVnX2dlbiRnZW51c19jb3VudCldKQoKIyBDb21wYXJlIHRoZSBjb3JyZWN0ZWQgb2JzZXJ2ZWQgZGlzdHJpYnV0aW9uIHdpdGggdGhlIHRoZW9yZXRpY2FsIGN1cnZlCmdncGxvdChDZXRhY2VhX29jY19hZ2dyZWdfZ2VuW0NldGFjZWFfb2NjX2FnZ3JlZ19nZW4kYWNjZXB0ZWRfcmFuayAlaW4lIGMoInNwZWNpZXMiLCAiZ2VudXMiKSxdLCAKICAgICAgIGFlcyh4PWdlbnVzX2NvdW50LAogICAgICAgICAgIHk9Z2VudXNfY2F0ZWdvcmllc19jb3VudCwKICAgICAgICAgICBzaXplPWdlbnVzX2NhdGVnb3JpZXNfY291bnQpKSArCiAgZ2VvbV9wb2ludCgpICsKICAKICBhbm5vdGF0ZSgibGluZSIsIHggPSAxOm1heChnZW51c19jb3VudF9hZ2dyZWcpLCB5PSBkZW5zX2FnZ3JlZwogICAgKm1heCgodGFibGUoZ2VudXNfY291bnRfYWdncmVnKS9hcy5udW1lcmljKG5hbWVzKHRhYmxlKGdlbnVzX2NvdW50X2FnZ3JlZykpKSlbYXMuZmFjdG9yKGdlbnVzX2NvdW50X2FnZ3JlZyldKSAvbWF4KGRlbnNfYWdncmVnKSkgKwogIAogIHNjYWxlX3hfY29udGludW91cyhuYW1lID0gIk51bWJlciBvZiBvY2N1cnJlbmNlcyBieSBnZW51cyIpICsKICBzY2FsZV95X2NvbnRpbnVvdXModHJhbnMgPSAibG9nMTAiLCBuYW1lID0gIk51bWJlciBvZiBjb3JyZXNwb25kaW5nIGdlbmVyYSAobG9nLXNjYWxlKSIpICsKICBzY2FsZV9maWxsX2Rpc2NyZXRlKG5hbWU9Ik9ic2VydmVkIGRpc3RyaWJ1dGlvbiIpICsKICB0aGVtZShwYW5lbC5ncmlkLm1ham9yLnggPSBlbGVtZW50X2JsYW5rKCksIAogICAgICAgIHBhbmVsLmdyaWQubWFqb3IueSA9IGVsZW1lbnRfYmxhbmsoKSkgKwogIGdndGl0bGUoIkNvbXBhcmlzb24gYmV0d2VlbiBleHBlY3RlZCBhbmQgb2JzZXJ2ZWQgZGlzdHJpYnV0aW9ucyBvZiBudW1iZXIgb2Ygb2NjdXJyZW5jZXMsIGFmdGVyIGFnZ3JlZ2F0aW5nIGluIGdlb3BsYXRlcyIpCgpnZW51c19jb3VudF9hZ2dyZWcgPC0gQ2V0YWNlYV9vY2NfYWdncmVnX2dlbltDZXRhY2VhX29jY19hZ2dyZWdfZ2VuJGFjY2VwdGVkX3JhbmsgJWluJSBjKCJzcGVjaWVzIiwgImdlbnVzIiksXSRnZW51c19jb3VudApkZW5zX2FnZ3JlZyA8LSBzYXBwbHkoMTptYXgoZ2VudXNfY291bnRfYWdncmVnKSwgZnVuY3Rpb24obil7CiAgICAgZXhwZWN0ZWRfZGlzdHJpYnV0aW9uKG4sIG9tZWdhLCBDZXRhY2VhX29jY19hZ2dyZWdfZ2VuW0NldGFjZWFfb2NjX2FnZ3JlZ19nZW4kYWNjZXB0ZWRfcmFuayAlaW4lIGMoInNwZWNpZXMiLCAiZ2VudXMiKSxdJHN0cmF0aWdyYXBoaWNfcmFuZ2VfZHVyYXRpb24pJHZhbHVlCiAgICB9KQpnZW51c19jb3VudF9jYXRlZ29yaWVzX2FnZ3JlZyA8LSB0YWJsZShnZW51c19jb3VudF9hZ2dyZWcpL2FzLm51bWVyaWMobmFtZXModGFibGUoZ2VudXNfY291bnRfYWdncmVnKSkpICAjIE51bWJlciBvZiBjYXRlZ29yaWVzIHdpdGggMSwgMiwgMywgLi4uIG9jY3VycmVuY2VzIG9mIHRoZSBzYW1lIGdlbnVzCmBgYAoKJFx0byQgVGhlIGNvcnJlc3BvbmRlbmNlIGlzIG11Y2ggbGVzcyBpbXByb3ZlZCB0aGFuIHdpdGggc3BlY2llcyBhZ2dyZWdhdGlvbiBiZWNhdXNlIHNvbWUgZ2VuZXJhIGhhdmUgYSBsb3Qgb2Ygb2NjdXJyZW5jZXMgZHVlIHRvIHRoZWlyIGhpZ2ggbnVtYmVyIG9mIHNwZWNpZXM6CgpgYGB7cn0KdGFibGUoZHJvcGxldmVscyhDZXRhY2VhX29jY19hZ2dyZWdfZ2VuWyhDZXRhY2VhX29jY19hZ2dyZWdfZ2VuJGFjY2VwdGVkX3JhbmsgJWluJSBjKCJzcGVjaWVzIiwgImdlbnVzIikpICYgKENldGFjZWFfb2NjX2FnZ3JlZ19nZW4kZ2VudXNfY291bnQ+MjUpLF0kZ2VudXMpKQpgYGAKCmBgYHtyIGZpZy53aWR0aD0xMCwgZmlnLmFzcD0wLjV9CmNvbmRpdGlvbnMgPC0gQ2V0YWNlYV9vY2MkYWNjZXB0ZWRfcmFuayAlaW4lIGMoInNwZWNpZXMiLCAiZ2VudXMiKQoKcDEgPC0gZ2dwbG90KENldGFjZWFfb2NjW2NvbmRpdGlvbnMsXSwgYWVzKHg9LWFnZV9ydW5pZikpICsKICBnZW9tX2hpc3RvZ3JhbShiaW53aWR0aCA9IDAuNSwgYWxwaGE9MC41LCBmaWxsPU5BLCBjb2w9InJlZCIpICsKICB4bGltKC1tYXgoQ2V0YWNlYV9vY2NbY29uZGl0aW9ucyxdJGFnZV9ydW5pZiktMSwgMSkgKwogIHlsaW0oMCwgMTAwKSArCiAgdGhlbWVfdm9pZCgpCgpwMiA8LSBnZ3Bsb3QoQ2V0YWNlYV9vY2Nfc2FtcGxlZCwgYWVzKHg9LWFnZV9ydW5pZikpICsKICBnZW9tX2hpc3RvZ3JhbShiaW53aWR0aCA9IDAuNSwgYWxwaGE9MC41LCBmaWxsPSJibHVlIikgKwogIHhsaW0oLW1heChDZXRhY2VhX29jY1tjb25kaXRpb25zLF0kYWdlX3J1bmlmKS0xLCAxKSArCiAgeWxpbSgwLCAxMDApICsKICB0aGVtZV92b2lkKCkKCnAzIDwtIGdncGxvdChDZXRhY2VhX29jY19hZ2dyZWdfZ2VuW0NldGFjZWFfb2NjX2FnZ3JlZ19nZW4kYWNjZXB0ZWRfcmFuayAlaW4lIGMoInNwZWNpZXMiLCAiZ2VudXMiKSxdLCBhZXMoeD0tYWdlX3J1bmlmKSkgKwogIGdlb21faGlzdG9ncmFtKGJpbndpZHRoID0gMC41LCBhbHBoYT0wLjUsIGZpbGw9ImdyZWVuIikgKwogIHhsaW0oLW1heChDZXRhY2VhX29jY1tjb25kaXRpb25zLF0kYWdlX3J1bmlmKS0xLCAxKSArCiAgeWxpbSgwLCAxMDApICsKICB0aGVtZV92b2lkKCkKCiMgcDEgKyBhbm5vdGF0aW9uX2N1c3RvbShnZ3Bsb3RHcm9iKHAyKSkgKyBnZ3RpdGxlKCJJbml0aWFsIG9jY3VycmVuY2VzIGRpc3RyaWJ1dGlvbiAocmVkKSBhbmQgY29tcGFyaXNvbiBhZnRlciBzdWItc2FtcGxpbmcgKGJsdWUpIikKIyAKIyBwMSArIGFubm90YXRpb25fY3VzdG9tKGdncGxvdEdyb2IocDMpKSArIGdndGl0bGUoIkluaXRpYWwgb2NjdXJyZW5jZXMgZGlzdHJpYnV0aW9uIChyZWQpIGFuZCBjb21wYXJpc29uIGFmdGVyIGFnZ3JlZ2F0aW5nIGluIGdlb3BsYXRlcyAoZ3JlZW4pIikKCnAxICsgYW5ub3RhdGlvbl9jdXN0b20oZ2dwbG90R3JvYihwMykpICsgYW5ub3RhdGlvbl9jdXN0b20oZ2dwbG90R3JvYihwMikpICsgZ2d0aXRsZSgiSW5pdGlhbCBvY2N1cnJlbmNlcyBkaXN0cmlidXRpb24gKHJlZCkgYW5kIGNvbXBhcmlzb24gYWZ0ZXIgc3ViLXNhbXBsaW5nIChibHVlKSBvciBhZ2dyZWdhdGluZyBpbiBnZW9wbGF0ZXMgKGdyZWVuKSIpCmBgYAoKJFx0byQgRGVsaW1pdGluZyBieSBnZW9sb2dpY2FsIHBsYXRlcyAoKyBhZ2UpIGluc3RlYWQgb2YgY291bnRyaWVzICgrIGFnZSkgbGVhZHMgdG8gc2ltaWxhciBkaXN0cmlidXRpb25zLCB3aXRoIGEgYml0IG1vcmUgb2NjdXJyZW5jZXMuCgpgYGB7cn0Kd3JpdGUudGFibGUoQ2V0YWNlYV9vY2NfYWdncmVnX2dlbltDZXRhY2VhX29jY19hZ2dyZWdfZ2VuJGFjY2VwdGVkX3JhbmsgJWluJSBjKCJzcGVjaWVzIiwgImdlbnVzIiksIGMoIm1pbl9tYSIsICJtYXhfbWEiKV0sCiAgICAgICAgICAgIGZpbGU9Ii4uL2RhdGEtY2V0YWNlYW5zL0NldGFjZWFfb2NjdXJyZW5jZXNfbWluX21heF9hZ2VfZ2VuZXJhX2NvcnJlY3RlZC5jc3YiLCBzZXA9IiwiLCByb3cubmFtZXM9RkFMU0UsIGNvbC5uYW1lcz1GQUxTRSkKYGBgCgojIENvbmNsdXNpb25zCgpTZXZlcmFsIGJpYXNlcyBhZmZlY3QgdGhlIGNldGFjZWFuIGZvc3NpbCByZWNvcmQ6CgogIC0gQklBUyAxOiBWZXJ5IHJlY2VudCBzYW1wbGVzIG1heSBoYXZlIGJlZW4gZGF0ZWQgd2l0aCBhIG1vcmUgcHJlY2lzZSBtZXRob2QgYW5kIGNvbnRhaW4gbXVjaCBtb3JlIGZvc3NpbHMsIHNvIHRoZXkgc2hvdWxkIGJlIHJlbW92ZWQgb3IgdHJlYXRlZCBzZXBhcmF0ZWx5CiAgLSBCSUFTIDI6IFNvbWUgb2NjdXJyZW5jZXMgc2hvdyBhIGhpZ2hseSB1bmNlcnRhaW4gZGF0aW5nICg+IDEwTXkpLCB0aGV5IGFyZSBleGNsdWRlZCB3aGVuIGNvbWJpbmluZyB0aGUgdW5jZXJ0YWludHkgaW50ZXJ2YWxzIGludG8gYSB1bmlxdWUgc3RyYXRpZ3JhcGhpYyByYW5nZSBwZXIgdGF4b24KICAtIEJJQVMgMzogU29tZSB0YXhhIGFuZCBnZW9sb2dpY2FsIHBlcmlvZHMgc2VlbXMgdG8gaGF2ZSBiZWVuIG92ZXJzYW1wbGVkLCBkdWUgdG8gdmFyaWF0aW9uIGluIHNwZWNpZXMgYWJ1bmRhbmNlLCBnZW9sb2dpY2FsIGZhY3RvcnMgb3IgaHVtYW4gdW5lcXVhbCBzYW1wbGluZywgCiAgICAxLiBJdCBzZWVtcyBwb3NzaWJsZSB0byBhZGVxdWF0ZWx5IHJlZHVjZSB0aGUgYWJ1bmRhbmNlIGJpYXMgYnkgc3Vic2FtcGxpbmcgdGhlIHJpY2hlc3QgdGF4YSwgYmFzZWQgb24gYSBtZXRyaWNzIG9mIG9jY3VycmVuY2UgZGVuc2l0eSAobnVtYmVyIG9mIG9jY3VycmVuY2VzIC8gc3RyYXRpZ3JhcGhpYyByYW5nZSkuIFVzaW5nIGNvbWJpbmVkIHN0cmF0aWdyYXBoaWMgcmFuZ2VzLCBpbnN0ZWFkIG9mIGFnZSB1bmNlcnRhaW50eSBpbnRlcnZhbHMsIGFwcGVhcnMgdG8gYmUgbW9yZSByb2J1c3QKICAgIDIuIEFuIGFsdGVybmF0aXZlIHNhbXBsaW5nIG1ldGhvZCBjb25zaXN0aW5nIGluIGFnZ3JlZ2F0aW5nIHRoZSBvY2N1cnJlbmNlcyBvZiB0aGUgc2FtZSB0YXhhIGZvdW5kIGluIHRoZSBzYW1lIGdlb2xvZ2ljYWwgZm9ybWF0aW9uIChvciB0aGUgc2FtZSBnZW9wbGF0ZSArIGVhcmx5IHN0cmF0aWdyYXBoaWMgaW50ZXJ2YWwgaWYgdGhlIGdlb2xvZ2ljYWwgZm9ybWF0aW9uIGlzIG5vdCBpbmRpY2F0ZWQpIHNlZW1zIHRvIHdvcmsgZXF1YWxseSB3ZWxsLCBhbmQgaXMgbW9yZSBwYWxlb250b2xvZ2ljYWxseSByZWxldmFudAogICAgCiAgICA=